Delete Firebase Messaging token on Android when device offline - android

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.

Related

App uninstall and re-install shows "firebase authentication not allowed" despite User is Null. Can we signOut or delete user or Login?

After the User has uninstalled the app, it doesn't un-authenticate the user. Even if the user is null, it calls onVerificationFailure(). Can I have it re-authenticate the new user or get the credentials of previous one despite it being null?
Firebase - Deleting and reinstalling app does not un-authenticate a user
Firebase FAuthData saved even after deletion of app
Log user out after app has been uninstalled - Firebase
I have found these cases for iOS and I do understand that the issue is similar to Android. However, neither signout() nor currentUser.delete() works in the case. At times currentUser is even null but I can't sign in again with this or newer user.
Also, android:allowBackup="false" doesn't solve the problem as suggested here with Android.
Firebase Auth saved after uninstall. How can I delete it?
My current code:
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser mUser = mAuth.getCurrentUser();
if (mUser != null) {
FirebaseAuth.getInstance().signOut();
mUser.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful())
Log.e(TAG, "Delete Success");
else
Log.e(TAG, String.valueOf(task.getException()));
}
});
} else
Log.e(TAG, "User Null");
The code is in onStart() of activity. It either returns User Null or moves to failure function. SHA-1 is verified and uploaded. Firebase authentication is enabled. Currently, only authentication by Phone Number is available to user end; no database or firestore is in use.
The other approach I tried (unsuccessfully) instead of deleting/signing out the user:
if (mUser.getPhoneNumber() != null)
//Log In Logic
else
//sign Up Logic
I expect the user to be able to log in or sign up, and not entirely be failed in verification process. Documents do not mention more than deletion or removal. Firebase docs even allow signout to be able to sign in with a different user. But it doesn't work here either.

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()

Who initialize connection for Firebase token?

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.

Firebase Auth getIdToken gets stuck after update

So the situation is as follows:
1) A user is logged in. the last token generated was a while ago and has expired. even if it hasn't, the issue doesn't hit.
2) An app update is installed. (Not android studio instant run thing, Actual signed apk with a higher app version and appversioncode)
3) User opens app and the regular code below which i use to refresh the id token runs.
4) None of the listeners get hit and there's never a time out
Is this a bug or am i doing something wrong here?
Clearing app data and restarting clears all problems. The code runs fine in this case. It only gets stuck after an update.
NOTE: i have set the forceRefresh boolean false as this code runs on every app launch and i don't want unnecessary id token creations getting called in case there's a limit on the generations. the false boolean does refresh the token if and only if it has expired.
FirebaseAuth.getInstance().getCurrentUser().getIdToken(false).addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
#Override
public void onComplete(#NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
//logic to proceed further
}
}).addOnFailureListener(new OnFailureListener() {
#SuppressLint("SetTextI18n")
#Override
public void onFailure(#NonNull Exception e) {
if(e instanceof FirebaseAuthInvalidUserException){
//Do stuff to log out the user session
}else{
//Some other exception occurred, let the user retry
}
}
});
P.S i do have a nullity check before all this to see if there indeed is a user.
For anyone wondering about this, I raised a ticket with Firebase support and it turns out that it's a bug in Firebase Auth 15.1.0
According to release notes, they had modified the token refresh logic and probably this is where the bug was introduced.
The system works fine up to 12.0.1 version according to my tests. Please do not update to 15.1.0 if you are planning to use a similar feature.

Android FirebaseUI Auth - How to reauthenticate?

Related Question: How does Firebase Auth UI deal with reauthentication?
(This question is for iOS, and is unsolved)
I would like to allow a user to update their email/password/etc with FirebaseUI on Android.
According to the guide, the "drop-in" UI provides:
Account Management - flows to handle account management tasks, such as account creation and password resets.
On GitHub, it looks like the AuthUI Management Page feature is still in progress (right?)
So, I've created my own account management page, but some of the actions are security sensitive and require reauthentication:
Some security-sensitive actions—such as deleting an account, setting a primary email address, and changing a password—require that the user has recently signed in. If you perform one of these actions, and the user signed in too long ago, the action fails and throws FirebaseAuthRecentLoginRequiredException.
The example code requires that we retrieve the credentials from the user before passing it to the reauthenticate:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// Get auth credentials from the user for re-authentication. The example below shows
// email and password credentials but there are multiple possible providers,
// such as GoogleAuthProvider or FacebookAuthProvider.
AuthCredential credential = EmailAuthProvider
.getCredential("user#example.com", "password1234");
// Prompt the user to re-provide their sign-in credentials
user.reauthenticate(credential)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.d(TAG, "User re-authenticated.");
}
});
However, getting the credentials from the user is non-trivial, since I allow sign in with Google, email, facebook, and phone number. For example, signing in with a phone number requires that a text be sent to the phone. This needs more than just an alert dialog asking for a password.
On Github, there was a merge for adding a reauthentication builder a few months ago, but I've been unable to find this function in the most recent FirebaseUI version. Something like AuthUI.createReauthIntentBuilder() would be perfect.
What is the best approach for re-authenticating a user with Firebase on Android? Can I use the AuthUI.createSignInIntent(), or is implementing my own reauthentication dialog really the only way?
Currently using: FirebaseUI Auth 3.1.2
mUser.updateEmail(cek_email).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(getActivity(), "succes", Toast.LENGTH_SHORT).show();
}
}
});
use method updateEmail

Categories

Resources