I want to know if I need to re-authenticate with Firebase if I call firebase.database().goOffline and then call firebase.database().goOnline() at a later time. It is not clear in the documentation.
https://firebase.google.com/docs/reference/js/firebase.database.Database#goonline
The online status of Realtime Database is not related to the state of the user's authentication. Authentication state is handled automatically by Firebase Authentication. The token that identifies the user is automatically refreshed every hour by the SDK, and you don't have to write any code to manage that. It doesn't pay attention to whether or not the Realtime Database thinks it's online or not.
Related
I use Firebase Firestore and Firebase Authentication in my project.
I am testing out what would happen if I go into firebase console and manually click the "Disable account".
I would expect that if the account is suspended, the authenticated user (test#mail.com in this case) will immediately receive error whenever a Firestore database is called (eg. getDocs(q) or setDoc()). The reason behind this assumption is that I assume Firestore tries to authenticate each call before doing CRUD.
However, after testing out, here is the test and result
Login user (test#mail.com)
Do a db read or write ensure everything works which it does
Go to firebase console and disable the account (test#mail.com).
Try to do another db read or write. The result here is that I was able to still read and write which is not what I expected.
So here are my questions
Is this a normal behavior?
Can I write Firebase security rule to overcome this issue?
It would be less idea if I have to check if user is logged in everytime I do a firestore call. But if that is what I have to do, how can I do that. I believe getAuth()and onAuthStateChanged is not really suitable in this case. Reason being getAuth() seems to only check the database the first time it is called. Any subsequence call it only checks the app memory and do not perform any network request at all (Verified by looking into console network tab). Which is kinda weird. And onAuthStateChanged does not listen to firebase state change, it only listens to if my app logs a user in or out.
Abit of background on what I am trying to achieve
I want to be able to lock a user out from my app by changing something from the db. And ideally not having to PING every few second .
Update:
It seems like it takes about 1-2 hour for my app to automatically recognise that the account has been disabled. It took takes alot longer than what I anticipated. I would still like to know if there is a better solution rather than wait though.
Firebase Authentication works with a combination of long-lived refresh tokens and short-lived ID tokens. The latter tokens are valid for one hour from the moment they are minted, and cannot be made invalid after they are minted.
So it may take up to an hour before your client gets a new token, and detects that its account has been disabled. You can force the client to update its ID token at any time by calling getIDToken(true). This will ensure the client has an updated ID token, but it won't invalidate the older ID token (since it's impossible to invalidate a bearer token).
What you'll want to do is write the UID or ID token to your database when you disable the user account, and then check for that in your security rules.
Also see the Firebase documentation on detecting token revocation.
Is there any way to get to know the a user is already logged in any other devices ?.
In Firebase Auth service.
Anyone please let me know is there any predefined provision in Firebase Auth.
UserMetaData has the last sign in time. You can also set auth state persistence to be either local, session, or none.
You could use these to approximate whether a given user could be authenticated elsewhere, but it doesn't seem like there's data on whether a user is definitely currently authenticated somewhere. For that you'd need to store login/logout data separately, such as in a a Firestore document for each user.
Note that the auth service doesn't typically know (or care) whether the user is actively using the app... it just issues each user an authentication token, which is used over some period of time to prove that they are who they say the are. The token can be invalidated/refreshed from time to time for security reasons (according to the persistence setting), but it's not an indication of whether they're "active". You don't mention your use case, but if you're trying to figure out whether users are on or offline (say for a chat application), you should look at Firebase's offline capabilities.
In my app using Firebase as back-end, I wanted to implement a new feature based on Firebase Storage to allow my users to save some files.
Knowing that my app can be accessed only by people who are paying a subscription, I'm already filtering the access to Firestore (used in my project to store user data) via a document that stores if the subscrition is valid or not and this is filtered by the Firestore security rules.
I saw that there is no linkage between Firestore and Storage, so I can't in the Storage security rules read my Firestore documents. So I had the idea to use CustomClaims to add to the Auth token an attribute if the subscription is valid or not.
After tinkering a bit with it, I noticed and checked that it takes up to an hour to client to have a refreshed token. Since my app follow roughtly this workflow:
I don't think that is a good user experience to wait for an hour to have access to a service the user just paid.
Is there something I didn't see ? Is there a way to circumvent this problem ? Is there an other way to have a refresh token than to force the user to logout ?
You can force the ID token to be refreshed with currentUser.getIdToken(true) with the JS SDK. There are similar methods for the other Client SDKs.
See the doc for more details.
I have a couple of http functions in my firebase project, because I prefer to hydrate, validate and update the data on the backend. I would like to use the automatic stackdriver logs, but I need to associate the log events with the authenticated user (the requests are authenticated). Is there any way to add some context to database updates? Or commit the changes in the name of the user (not the service account)?
Firestore triggers don't currently associate any information about the end user (not even if you're using Firebase Authentication and security rules), so you will have to write user information into each document in order to track who performed an action on it. It will not just appear in the environment or context.
If you go this route, I strongly suggest adding security rules that require the user to provide their Firebase Auth UID correctly in a document field, so you can be 100% sure it's correct.
Read this for more details: https://medium.com/firebase-developers/patterns-for-security-with-firebase-per-user-permissions-for-cloud-firestore-be67ee8edc4a
Is there a way to keep all the data local, and sync it online with firebase when the user decide to login in to the app?
I know about the offline capabilities of firebase, but I don't think they are meant for this use case.
Typically you'd use an anonymous login for that situation. The data will be synchronized with the Firebase server in that case, but the user doesn't have to sign in yet. For more information, see the documentation on anonymous auth.