Reputation: 36
In my toy chat application, I would like to set up a way to send notifications to users whenever other users send messages using Firebase Google Cloud Messaging. In my approach, I intend to capture the devices' registration tokens, and then later send notifications to those devices using Google’s Cloud Functions. Also, my application requires that users be authenticated.
To capture the tokens in my Firebase Realtime Database, I have sub-classed FirebaseInstanceIdService
as follows:
public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseInstanceIdService";
private static final String FCM_REG_TOKENS = "fcm_registration_tokens";
@Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "This device updated token: " + refreshedToken);
sendRegistrationTokenToServer(refreshedToken);
}
private void sendRegistrationTokenToServer(final String refreshedToken) {
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference();
dbRef.child(FCM_REG_TOKENS).push().setValue(refreshedToken);
Log.d(TAG, "sendRegistrationTokenToServer: NEW TOKEN: " + refreshedToken );
}
}
However, it appears that the above service runs immediately the application is launched, even before the SignInActivity is run. And, at this point, obviously I am yet to capture the details of the Firebase user to store the token in the correct database.
My gut feeling is that I am doing this incorrectly. What is the proper way to capture device registration tokens in order to send notifications to devices with those tokens?
Upvotes: 1
Views: 2062
Reputation: 598817
FCM tokens are tied to an installed app (that's why they're called Instance ID Tokens), and not necessarily to a specific Firebase Authentication user (since the app may not even require the user to sign in).
Your code is the correct way to capture the token for the app instance.
If you have a requirement to associate the token with a user, then you'll need some code to check both values. A simple way to do this is to get the current user from Firebase Auth in your service:
@Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "This device updated token: " + refreshedToken);
sendRegistrationTokenToServer(refreshedToken);
}
private void sendRegistrationTokenToServer(final String refreshedToken) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference();
dbRef.child(FCM_REG_TOKENS).child(user.getUid()).setValue(refreshedToken);
Log.d(TAG, "sendRegistrationTokenToServer: NEW TOKEN: " + refreshedToken );
}
}
This keeps a single token for each unique UID. Note that the correct data structure here depends on your actual use-case, since the same user may use your app on multiple devices and thus have multiple tokens.
Upvotes: 4