I have an ASP.net MVC server from where I want to send push notifications to my Android App. I have already implemented Firebase Messaging in the app and the notifications are working fine when sent from Firebase dashboard.
I have tried sending push notification using the server by sending a post request, but the request requires a to field. Earlier we used to send registration id provided by GCM there. Now since Firebase is handling it, how can I fetch the registration id to be put in the to field using Firebase SDK in Android?
Hi and thanks for using Firebase Cloud Messaging!
You can fetch the registration-id calling:
FirebaseInstanceId.getInstance().getToken();
Differently from the GCM sdk, the new library automatically takes care of fetching the token as soon as possible, and then it caches it locally.
The above method will return the token, if available, or null if the fetching phase is still in progress.
You can use the callback onTokenRefresh() to be notified when the token is available or has been rotated.
public class InstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
sendRegistrationToMyServer(refreshedToken);
}
}
More info here: https://firebase.google.com/docs/cloud-messaging/android/client#sample-register
Related
I understand that the FCM token renews itself if one of the following happens.
-The app deletes Instance ID
-The app is restored on a new device
-The user uninstalls/reinstall the app
-The user clears app data.
The following can be used at the App side to monitor Token renewal.
Monitor token generation
The onTokenRefreshcallback fires whenever a new token is generated, so
calling getToken in its context ensures that you are accessing a
current, available registration token. Make sure you have added the
service to your manifest, then call getToken in the context of
onTokenRefresh, and log the value as shown:
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(refreshedToken);
}
My question is, when the app is terminated, the token expires and there is no way for the FCM server to know what the new token is for the device (if exist). So when I send a notification/data message to this device, the server fails to send it to the device as it doesn't know where to send it to (as there is no valid token). How do I make sure that in such situations I can notify the device ? I dont do a customer token generation. So the it seems to refresh the token now and then. How do I increase the validity of my token ?
You will need to check for an error when sending the message, and pay attention to the error codes, as listed in the documentation. You should stop using the token if you get the error messaging/registration-token-not-registered.
I am using FCM in my project and my application is register with two FCM project (two sender ID).
Now i want to handle token refresh.And as per document i will get below call back
#Override
public void onNewToken(String token) {
Log.d(TAG, "Refreshed token: " + token);
}
but have may i know which token is updated ?
token updated for sender_id_1 or token updated for sender_id_2 ?
Question 2 : If i receive onNewToken call back with newToken value and if i do not pass that value to server and server try to send push on older token, then what will happen ? what error i will received from FCM ?
Thanks
Looking at the docs for onNewToken() (emphasis mine):
Called when a new token for the default Firebase project is generated.
This is invoked after app install when a token is first generated, and again if the token changes.
Default project points to the first project.
Sending to an expired token would result to a NotRegistered error
I'm using this well known code to save a new firebase token on my server (from: Retrieve the current registration token):
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(refreshedToken);
}
The problem is, that if the user installs the app on some other device, the same code will be executed and the former firebase token will be overridden by the new one.
So I have to distinguish between the devices, but how can I do it? Device name is for sure not unique enough for this.
EDIT: unfortunately, the suggestion by Bob Snyder did not work. The FirebaseInstanceId#getId() is always different if I remove the App data (cache) or reinstall the app.
The token is unique to each device and includes the app instance ID. The 11-character instance ID, which is the same one returned by FirebaseInstanceId.getInstance().getId(), appears first, followed by a colon, and the remainder of the token. Example:
eiURDSe_P4q:APA91bFvtCzK...LRpzvQOSdNKioklO
You can use the instance ID as a unique key to store the token on the server.
I have problem with Firebase, i get the token with FirebaseInstanceIdService service with method onTokenRefresh
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.i(TAG, "Refreshed token: " + refreshedToken);
}
I take the from the Android Studio Logcat( select it and copy/paste ) and i paste Postman tool.
With some token I don't have problem but with other I have the error
NotRegistered
Example of token notRegistered:
e98tZENV-FY:APA91bEBScMMWJSDtU08ZaXy172KPSle_dC5TFPUHiZ_OCg6o03Jmk0yi288v3byLVfLVUkksGJ7m-QR2swMUPlMlmwFiPWswLrKd9UTbtdbx0l02k0OhT84YAC0QLz6UCyhsn-poLwp
So some things that are sure ( because some token are sending and same app, same server, same android studio, etc):
The Server Key is ok.
The Google Service Json is ok.
The token is copy/paste correctly
Can be some issue with some special character or a bug of Firebase?
Thanks!!!
I have an Android app which receives push notifications. I was wondering if there was a more straightforward method to store a FCM token and user ID on a external db given that right now I'm writing my own FirebaseInstanceIdService. sendRegistrationToServer method. Like this
public class TokenRegistrationService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
// My custom manager
}
private void sendRegistrationToServer(final String FCMToken) {
// Here I can send FCMToken to my db
}
}
Is there any other way for me to get the token and send it?
I'm assuming you mean a more straightforward way than extending FirebaseInstanceIdService. If so then you should note that the token is generated whether or not you extend this class.
To retrieve the token you can simply get an instance of InstanceID and call getToken.
String token = InstanceID.getInstance().getToken();
Also note that if you are not requesting the token in the FirebaseInstanceIdService onTokenRefresh callback, getToken will return null if the token retrieval process has not yet completed and will return the token once it has been retrieved.
The token retrieval happens as soon as your application starts so if you don't need the token very early on first run, calling getToken will likely be sufficient. If you need the token or refreshed versions as soon as they are available then you would need to extend FirebaseInstanceIdService and override onTokenRefresh.
Is there any other way for me to get the token and send it?
For generating the registration token, I'm pretty sure there is no other way than just using the FirebaseInstanceID service.
For when sending the token to your server.. I'm not sure what the question is here. Isn't sending the token directly to your app server after it was generated straightforward enough? Or am I missing something? Do expound.