Who initialize connection for Firebase token? - android

My applicaion needs to work in secure environment and it can connect
only with speficic server. In other words, traffic that goes outside our app
is restricted. Because of that I have some doubts about Firebase notifications
functionality in this application.
I need to get Firebase token in order to send it to our server.
Ofcourse Firebase's server needs to identify client device in some way. I assume
that before receiving new token, some part needs to send data (like device id) to Firebase server in order
to generate that token that will be send back to me. So, the questions is... Who is responsible
for initializing this process? Under the hood, does the system do the work or my application?

For get token from firebase, you just need to do :
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w("token", "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
token = task.getResult().getToken();
Log.w("token", token);
}
});
You don't need to send anything.
For example, in my app I execute this code in SplashScreen, in this case the token can be directly send with the user login request.

Related

Delete Firebase Messaging token on Android when device offline

I'm implementing the logout procedure of my Android Mobile application. In particular I want to delete the Firebase Cloud Messaging Token when the user logs out from the app.
To do so I have implemented a method called revokeFirebaseToken which internally uses the FirebaseMessaging API to delete the token as follows:
private Task<Void> revokeFirebaseToken() {
// This will probably throw a onNewToken message
return FirebaseMessaging.getInstance().deleteToken();
}
In particular this the FirebaseMessagin deleteToken returns a Task which is asynchronously completed by Firebase. I handle the result with an onCompleteListener as follows:
revokeFirebaseToken().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
//some logic
} else {
//other logic
}
}
});
If the application is online everything works well.
The problem raises when for some reasons the application is offline; in this scenario the deleteToken raises an exception during the Task execution.
Is there a way to let the revoking token procedure working when device is offline? (Maybe I'm missing something in the Firebase configuration files)
Thanks a lot for any suggestion.

How to get FCM token for the device that don't have Google play services in android studio?

I have created an Android app in which I am using Firebase cloud messaging to send push notifications to the device. I have two devices, one have updated google play services (device A) but the other one don't (device B).
I am able to get the FCM token for device A and send the notifications successfully.
When I try to get the FCM token for device B then I received the following error message:
java.io.IOException: MISSING_INSTANCEID_SERVICE
I have tried to side load Google play services but it didn't work.
I have searched a lot but couldn't find any solution.
I really need to get the FCM token for Device B
This is how I am getting the FCM token
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult> () {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.d("cloudMessage", "getInstanceId failed", task.getException());
}else if(task.isSuccessful ()) {
try {
// Get new Instance ID token
String token = task.getResult ().getToken ();
// Log and toast
Log.d ( "cloudMessage", "Token: " + token );
}catch (Exception ex){
}
}
}
});
It's currently not possible to use FCM on devices without Play services. Play services not only gives you the device token, but it also handles the receipt of messages and delivers them to your app.

How do I use idToken with Firebase in Android

I'm making an Android app that will be using a REST API that I'm building in Firebase Functions and I have a question regarding user authentication.
As far as I've gathered, I have to send the user's idToken to the API with every HTTP call, to verify that the user is logged in and can access the API resource. So far so good.
I'm following this guide for sending the idToken:
https://firebase.google.com/docs/auth/admin/verify-id-tokens
What confuses me is that with that piece of code, it seems that I have to build all my code within the "if (task.isSuccessful())" part to be able to use the idToken, since I can't return any values from that inner class, to be used elsewhere in the app.
Isn't that impractical, since it would mean that I have to fetch the idToken every time I want to make an HTTP call, instead of reusing the one I've already found?
I considered storing the idToken in a cookie, but it seems that cookie would still be "locked" to the inner class, isn't that right?
How do (normal) people normally do this?
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getIdToken(true)
.addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
public void onComplete(#NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
String idToken = task.getResult().getToken();
// Send token to your backend via HTTPS
// ...
} else {
// Handle error -> task.getException();
}
}
});
there are two ways to call firebase functions from android app
1;) as a rest api
2:) using firebase functions library to call it directly (easier)
currently you are trying to use first option . drawbacks of this way is that you need to send id token with each request and verify it in cloud functions .
if you use 2nd way then you won't have to send idtoken yourself and firebase library will take care of that
check this link to know how to make direct function calls
https://firebase.google.com/docs/functions/callable
but if you want to keep using first way then you need to save the idtoken in local storage like this
public static void setAccessToken(Context context,String val){
PreferenceManager.getDefaultSharedPreferences(context).edit().putString("idToken",val).apply();
}
public static String getAccessToken(Context context){
return PreferenceManager.getDefaultSharedPreferences(context).getString("idToken",null);
}
call setAccessToken() within callback once when you login and when you need to call a function you can get the previous stored token with getAccessToken()

Firebase Login multiple provider with same email

I want my user who logged In first using FB to be able to log out and log in again using his/her google (same email).
What should I do? I read this https://firebase.google.com/docs/auth/android/account-linking ,but I don't quite understand. I thought the linking is to link accounts, regardless of the email.
While what I'm thinking is firebase identify user by email, so if I successfully log in and out from FB or Google by using same email, then firebase should know its the same user.
in the account-linking docs above, says that we need to get the credential/tokenID and call linkwithcredential , like this :
mAuth.getCurrentUser().linkWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Log.d(TAG, "linkWithCredential:onComplete:" + task.isSuccessful());
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful()) {
Toast.makeText(AnonymousAuthActivity.this, "Authentication failed.",
Toast.LENGTH_SHORT).show();
}
// ...
}
});
my questions are:
where I call this ? do I need to call it every login ?
then do I also need to get the credential for every provider each time I login ?

In what period does the firebase's app token changes and how to manage it?

I am new to firebase I am learning it like a toddler learning to walk. So far I have managed to send a message to my own phone using a token generated for my phone by firebase framework. Now here's where it gets tricky (in my opinion). There is a method called onTokenRefresh() in the FirebaseInstanceIdService extended service. Since it is called refresh, Then I am assuming that it will change. I want to know when this token is created and when will it be changed?
And if it changes, suppose I send a message to a device with token 'A' which is offline for now, so it will be queued. Now when the device gets online, it will "refresh" the token to 'B'. Now as the message was supposed to be delivered to token 'A', the message will never be delivered. How can I manage this situation?
The token is generated, after the app is first launched, as soon as the phone can connect to the Google servers. Due to the required connectivity this might not happen immediately, but in most of the cases it will happen in few seconds after the user open the app.
As soon as the token is generated the method onTokenRefresh() is called.
As you pointed out the token can change, in which case the onTokenRefresh() method will be called again.
The refresh event is somehow rare, don't expect to see it often at all.
When the refresh token happens, all the messages that have been "successfully" sent (the API returned you a message-id) to the old token will be delivered.
Finally, even after the refresh happened the old token will still be working for a short period, to allow the app to communicate the new token to its back-end.
On initial startup of your app, the sdk of FCM generates the registration token for the client app instance. As above said, It is a rare event. To be specific,The registration token may change when:
The app deletes Instance ID.
The app is restored on a new device
The user uninstall/reinstall the app
The user clears app data.
Instance ID provides a unique ID per instance of your apps.Instance ID provides a simple API to generate security tokens that authorize third parties to access your app's server side managed resources.The Instance ID server can even tell you when the device on which your app is installed was last used.We can use this to decide whether to keep data from the app or send a push message to re-engage with the users.
Every time the device token is changed, It is reflected in onTokenRefresh() method.For getting the device token when it is changed, we can call this method to get the refreshed token.
and to get the device token at any time we can use FirebaseInstanceId.getInstance().getToken() method to get the current device token.It takes a bit of time to get the device token.
Click here to read more about accessing device registration token.
onTokenRefresh() and FirebaseInstanceIdService are deprecated.
This call is also deprecated FirebaseInstanceId.getInstance().getToken()
Instead, You should override onNewToken(String token) in FirebaseMessagingService. This method triggered when the token is changed. Once you override this method, you can safely remove FirebaseInstanceIdService whcih contains onTokenRefresh().
When token can change?
App deletes Instance ID
App is restored on a new device
User uninstalls/reinstall the app
User clears app data
How to retrieve the current token:
by calling FirebaseInstanceId.getInstance().getInstanceId():
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = task.getResult().getToken();
// Log and toast
String msg = getString(R.string.msg_token_fmt, token);
Log.d(TAG, msg);
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
For more info:
https://firebase.google.com/docs/cloud-messaging/android/client
For Managing tokens for specific sender id (other than the default sender id),
check here

Categories

Resources