The situation: We are building an app in both Swift (for iPhone) and Kotlin (for Android). The app collects data from a bluetooth device and submits it to a FileMaker 18 database where we mine the information for our clients. The API requires us to POST a login to get a session token (called authToken), which is the first RESTful command. With the authToken, we're allowed to POST a record to the database (the second RESTful command).
In Swift, both RESTful commands work fine, and we've gotten data from the app every single time. In Kotlin, only the first RESTful command works (the one to acquire the authToken). The second one keeps returning an error claiming that we've provided an "invalid FileMaker Data API token," despite the fact that we're using the token we just acquired less than a second prior... and as far as we can tell, the requests in Kotlin are not functionally different than the ones in Swift.
The particular headache we're dealing with is that the POST for the authToken is working just fine in Kotlin, which means it doesn't have anything to do with the way Kotlin formats the RESTful command versus Swift. And the second request is made exactly the same way, which makes it particularly puzzling why it should be giving us any trouble.
We have even gone so far as to generate a token via Kotlin and plug it into Swift, and Swift was able to post to FileMaker with that token without authentication issues. This tells us that there is something about the way the token is being packaged in Kotlin that is resulting in it being invalidated somehow.
Any insight is greatly appreciated.
SWIFT
getAuth()
let url = URL(string: "https://<host>/fmi/data/vLatest/databases/<DB>/sessions")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Basic <login>", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
Response:
{"response":{"token":"<authToken>"},"messages":[{"code":"0","message":"OK"}]}
postToFM()
let url = URL(string: "https://<host>/fmi/data/vLatest/databases/<DB>/layouts/POSTin/records")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer " authToken, forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
Response:
["messages": <__NSSingleObjectArrayI 0x28169b760>({code = 0;message = OK;}),"response":{modId = 0;recordId = <number>;}]
KOTLIN
getAuth()
val url = URL("https://<host>/fmi/data/vLatest/databases/<DB>/sessions")
val conn = url.openConnection() as HttpURLConnection
conn.requestMethod = "POST"
conn.doOutput = true
conn.useCaches = false
conn.setRequestProperty("Authorization", "Basic *login*")
conn.setRequestProperty("Content-Type", "application/json")
Response:
{"response":{"token":"<authToken>"},"messages":[{"code":"0","message":"OK"}]}
postToFM()
val url = URL("https://<host>/fmi/data/vLatest/databases/<DB>/layouts/POSTin/records")
val conn = url.openConnection() as HttpURLConnection
conn.requestMethod = "POST"
conn.doOutput = true
conn.doInput = true
conn.useCaches = false
conn.setRequestProperty("Authorization", "Bearer $authToken")
conn.setRequestProperty("Content-Type", "application/json")
conn.setRequestProperty("Content-Length", fieldData.length.toString())
Response:
{"messages":[{"code":"952","message":"Invalid FileMaker Data API token (*)"}],"response":{}}
(Edited to add missing code)
CodePudding user response:
As it turns out, when zipping the code from Swift/Mac and bringing it over to Kotlin/PC, some invisible characters slipped in, either in the authorization header or in the URL (I'm not sure which unfortunately). When the presumptively working code/URLs were copied from the Swift files to the Kotlin files, the invisible characters were brought along, causing the issue. After retyping the code and URLs manually, the app was able to successfully POST the data to our database.