I've recently discovered that Firebase Auth saves itself on the device even after my app is uninstalled. I can't figure out how to REMOVE this old Auth info.
I don't want a user to still be signed in after uninstalling and reinstalling the app. If for no other reason than my own testing of what I expect to be "clean installs" on the same device.
I understand there is no easy way to capture an uninstall event, so I want to clear out any potential old Auth info on the first launch.
So I added code (which seems to work fine) to check if this is the first launch:
Boolean firstRun = prefs.getBoolean("firstrun", true);
if (firstRun) {
// delete everything an old user could have left behind
// ==> This is where I need help <==
prefs.edit().putBoolean("firstrun", false).apply();
} else {
// move along, not the first launch
}
I've tried (unsuccessfully):
FirebaseAuth authData = FirebaseAuth.getInstance();
authData.signOut();
These calls also seem to be the advice in this related question for iOS, but I haven't been able to apply its wisdom:
Firebase - Deleting and reinstalling app does not un-authenticate a user
Even after calling signOut() the app keeps logging me in under the old account!
My "logout" button uses FirebaseAuth.getInstance().signOut(); and works. Is there something odd (possessed?) about this "old" Auth instance that is being saved after an uninstall that it just won't die?
Specifically when I uninstall and then install/run from Android Studio:
at first authData and currentUser both are not null
I call the above code, trying to get rid of this old user
3 millisecond later (immediately after I call that
code) they are still NOT NULL.
Another 2 milliseconds, currentUser IS NULL (yay?)
Another 71 milliseconds... still null (so far so good)
Just under a second later... I'M SIGNED IN AS THE OLD USER?! How is this possible?
In the Firebase Console under Authentication, this account is shown as last signed in 6 days ago. So it's not somehow getting re-signed-in.
Does anyone know how to remove FirebaseAuth data from a device? I don't want to "delete" the user account, just remove all traces of it from this device.
Oddly enough, the account I keep getting unwillfully logged in under isn't even the last account that logged into my app on this device. And this was never a problem in the past (hence my not even knowing that Firebase saved Auth after uninstall). So it looks like Auth info isn't always saved after uninstall... but when it happens it's impossible to remove?
Any help much appreciated!
Add android:allowBackup="false" in your <application> in manifest:
From the docs:
android:allowBackup
Whether to allow the application to participate in the backup and restore infrastructure. If this attribute is set to false, no backup or restore of the application will ever be performed, even by a full-system backup that would otherwise cause all application data to be saved via adb. The default value of this attribute is true.
Try also FirebaseAuth.getInstance().getCurrentUser().delete
Firebase stores auth info in shared preference with file names starting with "com.google.firebase.auth.api.". Therefor if you delete these files as part of your log off flow it would help the purpose.
public void clearFirebaseAuthInfo(Context ctx)
{
File dir = new File(ctx.getFilesDir().getParent() + "/shared_prefs/");
String[] children = dir.list();
for (int i = 0; i < children.length; i++)
{
if(children[i].contains("com.google.firebase.auth.api."))
{
new File(dir, children[i]).delete();
}
}
}
Related
I'm not going to paste any code because I receive the desired behavior when a user creates account with a phone number in firebase auth.
My problem is after an app update, firebaseUser.getCurrentUser is null despite the fact that the user is already signed up.
My question:
How do I mimic a behavior like WhatsApp which doesn't require the user to always go through OTP after every app update?
Iv tried using authState:
auth.addAuthStateListener(firebaseAuth -> {
user = firebaseAuth.getCurrentUser();
if(user == null)
signUp() });
Hoping after update user won't be null. But it's always null after updating the app.
Actually what I didn't realize is that I was trying to mimic an update behavior by installing and uninstalling the app. Turns out token credentials are lost in the process. I just assumed Firebase attaches to the device identity some how, some where. I admit I need some instruction
My app is not automatically logging in when I restart the Android emulator. I believe previously it was doing so - though this might have been a bug caused by some bad code I have since ironed out. So to troubleshoot this problem I first need to discover whether or not this is simply a feature of the emulator.
Here is my code. I've confirmed that it successfully logs into FirebaseAuth and creates a user. According to documentation, automatically logging in on reboot should be as easy as this:
#Override
public void onStart() {
super.onStart();
//Get Firebase auth instance
auth = FirebaseAuth.getInstance();
// Check if user is signed in (non-null)
firebaseUser = auth.getCurrentUser();
}
The emulator has no bearing on the way Firebase Auth actually works. The problem is almost certainly that you're asking the SDK if the user is signed in before the SDK is certain about that. Instead of calling auth.getCurrentUser() you should use an auth state listener to get a callback when the final authentication state of the user is known. It might not be known immediately at launch, as the user's token might have expired and need to be refreshed at the server. This takes time.
Your app should wait until this auth state listener indicates that the user is actually signed. This means that your listener will actually be the thing to move your UI along to do things like make queries and present data to the user.
I have a DispatchActivity as my Launcher Activity, which is meant to check if there is a user currently signed in. If the user is signed in, I send them to their ProfileActivity. Otherwise, I send them to a LogInActivity. Here is my code in DispatchActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dispatch);
//.....................
auth = FirebaseAuth.getInstance();
authListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
launchProfileActivity();
} else {
// User is signed out
launchLoginActivity();
}
}
};
}
#Override
public void onStart() {
super.onStart();
auth.addAuthStateListener(authListener);
}
#Override
public void onStop() {
super.onStop();
if (authListener != null) {
auth.removeAuthStateListener(authListener);
}
}
No matter what I do, firebaseAuth.getCurrentUser(), never returns null on my primary testing device. According to the Docs, getCurrentUser() will be null unless there is a User Currently Signed in. When I Log some of this User's details, they are consistent with a "Test" user I created previously, (i.e. calling user.getEmail() returns "email#example.com".
This is problematic, as I most certainly don't have any users in my Console's User Database (In Authentication/Users). I deleted this test User from the database some time ago, and the database is empty.
I tried running the App on another device, and it executed properly. However, performing a fresh install on my primary testing device does not fix the problem.
Question:
As far as I can see, the issue is related to some kind of persistent user state with my device; since running a different device works fine. Since I haven't deliberately configured this to occur, I would like to know what is causing this inconsistency between my Auth User Database and the Device.
If the Database is empty, where is auth.getCurrentUser() getting this previously deleted user object from?
Thank you.
Firebase Authentication will cache an authentication token for the user when they're signed in. This prevents having to authenticate every little interaction the user makes with other services provided by Firebase. This token gets automatically refreshed periodically, but until then, the SDK assumes that the token represents the user. You'll find that the token will expire after some time, or you can force the issue by uninstalling and reinstalling the app, or clearing its data.
Authentication works regardless of the contents of your Realtime Database. They are independent from each other, except where security rules limit access to the currently authenticated user.
In Your Manifest File Add The Following
In the <manifest> tag (at the end)
xmlns:tools="http://schemas.android.com/tools"
Then in the <application> tag (at the begining)
tools:replace="android:allowBackup"
android:allowBackup="false"
android:fullBackupContent="false"
just as #Doug Stevenson mentioned above firebase saves some data on the phone adding these tags will ensure that that does not happen... so when you uninstall the app and install it again it will clear all the data associated with the app.
I had the same exact question and could not find the answer to this problem anywhere. I tried everything. I don't know why this works but I restarted my phone and it happened to fix everything. Super late but hope it helps for anyone else with the same problem.
My login system uses SharedPreferences to store information about the user. The main two variables for the login system are:
loggedin - boolean
userID - int of the userID that's logged in (primary key on the DB)
When the user logs in, loggedin is set to 1 and the userID is set to the user ID fetched from the DB. When the logout button is pressed loggedin is set to 0 and userID set to null.
Situations:
I log in, close the app and repoen it = fine, still logged in to the correct account
I log in, then logout, close & reopen the app = fine, comes up with login screen
I carry out invalidate caches and restart in android studio = fine, stays logged in on the correct account.
Now here's the one that's going wrong: If I login, then uninstall the app off my phone and press run on android studio the app launches and logs in to a really old account that no longer exists on the DB; and I can't work out why this is happening.
My only thought is there is a userID stored on the device that isn't being removed, but that could be completely wrong. Any ideas?
I've added some log tags throughout the code and before the app is uninstalled the userID is correct and when it's been reinstalled it's the old one.
Shared Preferences are always cleared along with uninstalling app.
But since android-21 Backup task stores preferences by default to cloud. Later when you uninstall then install newer version .You are probably going to use restored preferences. To avoid that, just add this to your manifest ( or at least manifest for debug). -
<application ...
android:allowBackup="false">
...
</application>
Read this:http://developer.android.com/guide/topics/data/backup.html
It's Important to mention here that process of backup is blackbox .. you don't know when it starts, and period between checks ... so better for developing to disable it.
I am trying to submit a status from my application to Window's live, the user starts the app, gets asked to give my app permissions to do this, and once granted I have a live session object and I can update their status. This works perfectly.
However, if the user closes the application and then opens it again, they are again asked to approve my app for this action. Every time.
Now the live documentation says you can obtain a refresh token (which I do) to prevent this, problem is the access token and the refresh token are all baked in the LiveConnectSession, so when my application is closed this object is destroyed and the user is asked to give the app permissions again.
So what I'd like to know is if anyone knows a way of recreating that object when the application starts (if I stored the token and refresh token) or a way of saving the object onDestroy()..
Iterable<String> scopes = Arrays.asList("wl.signin", "wl.share", "wl.offline_access" );
this.auth.login(this, scopes, this);
public void onAuthComplete(LiveStatus status, LiveConnectSession session, Object userState) {
if(status == LiveStatus.CONNECTED) {
Log.d("", "Signed in.");
client = new LiveConnectClient(session);
stuck with the same issue using Windows Phone..
I have tried serializing the session, which does not work because the session class has no default constructor.
EDIT:
after two full days searching for the mistake I was making, I finally found out what I was doing wrong: I have to use the wl.offline_access scope to make this work!
Now everything is fun again. Can't believe that this was the problem. Tested & working. Nice!
As I can see, you are using the offline scope, so that's not the problem for you.
But I have found out more:
there are two ways to connect to Live (in C#, I don't know how the methods are called in Java):
use LiveConnectClient.LoginAsync (which comes with GUI)
use LiveConnectClient.InitializeAsync (which is UI less and connects in background)
So if your application is already connected, use the second one to gain access to a new session object.
AFAIK, this object is valid for one year, after that, the user has to sign in again. But don't quote me on that.
Please let me know if this works for you.