如何通过URL参数发送FCM Token?及提交存储的FCM Token至指定API
Hey there! Let's tackle your two FCM token-related questions clearly and practically:
Sending an FCM token via URL parameters is feasible, but you need to prioritize URL encoding first—FCM tokens often include special characters like /, =, or + that can break parameter parsing if left unencoded.
Here's the step-by-step approach:
- Encode the token: Use platform-specific methods to make the token URL-safe:
- Android: Use
URLEncoder.encode(fcmToken, "UTF-8") - iOS: Use
fcmToken.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) - Web: Use
encodeURIComponent(fcmToken)
- Android: Use
- Construct the full URL: Append the encoded token and username as query parameters to your API endpoint. For example:
https://your-api-domain.com/save-token?username=jane_doe&fcmToken=your_encoded_token_here
Important Note:
URLs have length limits (most servers cap GET requests around 2KB). While FCM tokens are typically short enough, if you run into issues or want a more secure approach, switch to a POST request—it avoids length restrictions and is better suited for sensitive data like tokens.
Let's break this into actionable steps, using Android as an example (the logic translates easily to other platforms):
Step 1: Retrieve stored values from SharedPreferences
First, pull the saved username and FCM token from your SharedPreferences instance:
// Kotlin example val sharedPref = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE) val username = sharedPref.getString("stored_username", "") ?: "" val fcmToken = sharedPref.getString("stored_fcm_token", "") ?: ""
// Java example SharedPreferences sharedPref = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE); String username = sharedPref.getString("stored_username", ""); String fcmToken = sharedPref.getString("stored_fcm_token", "");
Step 2: Validate the data
Before sending, double-check that neither the username nor token is empty—there's no point sending a request with missing data:
if (username.isEmpty() || fcmToken.isEmpty()) { Log.e("TokenSender", "Username or FCM token is missing!") return }
Step 3: Send the POST request (with JSON body)
Since your API expects a JSON payload, we'll cover two popular approaches for Android: OkHttp and Retrofit.
Option A: Using OkHttp
// Add OkHttp dependency to your build.gradle first! val client = OkHttpClient() // Build the JSON body val jsonBody = JSONObject().apply { put("username", username) put("fcmToken", fcmToken) } val requestBody = RequestBody.create( MediaType.parse("application/json; charset=utf-8"), jsonBody.toString() ) // Build the request val request = Request.Builder() .url("https://your-target-api.com/save-token") .post(requestBody) .build() // Send the request asynchronously (avoid blocking the main thread!) client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { // Handle network errors, timeouts, etc. e.printStackTrace() // You could show a toast or log the error here } override fun onResponse(call: Call, response: Response) { response.use { if (it.isSuccessful) { // Success! Parse the response if needed val responseMsg = it.body?.string() Log.d("TokenSender", "Token sent successfully: $responseMsg") } else { // Handle API errors (4xx/5xx status codes) Log.e("TokenSender", "API Error: ${it.code}") } } } })
Option B: Using Retrofit (cleaner for structured APIs)
First, define a data class and API interface:
// Data class matching the API's expected payload data class TokenRequest(val username: String, val fcmToken: String) // API service interface interface TokenApiService { @POST("save-token") suspend fun sendToken(@Body request: TokenRequest): Response<Unit> }
Then set up Retrofit and make the call:
// Add Retrofit and Gson converter dependencies first! val retrofit = Retrofit.Builder() .baseUrl("https://your-target-api.com/") .addConverterFactory(GsonConverterFactory.create()) .build() val apiService = retrofit.create(TokenApiService::class.java) // Call the API in a coroutine (avoid main thread blocking) CoroutineScope(Dispatchers.IO).launch { try { val response = apiService.sendToken(TokenRequest(username, fcmToken)) if (response.isSuccessful) { Log.d("TokenSender", "Token sent successfully!") } else { Log.e("TokenSender", "API Error: ${response.code()}") } } catch (e: Exception) { // Handle network exceptions e.printStackTrace() } }
Key Tips:
- Add Internet Permission: Don't forget to include
<uses-permission android:name="android.permission.INTERNET" />in yourAndroidManifest.xml. - Background Execution: If you're sending the token on app startup, use WorkManager instead of a simple coroutine to ensure the request completes even if the app is backgrounded.
- Retry Logic: Add retry mechanisms for network failures (OkHttp has built-in interceptors for this, or you can implement your own).
内容的提问来源于stack exchange,提问作者Anand Singh

