FIREBASE - reauthenticateWithCredential and Database - firebase

I've been having some problems with the "reauthenticateWithCredential" method.
I need to be able to delete a user from my application and erase some database nodes with user's data.
The problem is, whenever I call "reauthenticateWithCredential" and receive a positive promise, all future attempts to access my firebase database are simply ignored...no logs or permission errors are shown on the browser console.
I've tried signing the user again, calling other functions outside of the reauth function, restarting Firebase after the reauth but none of these worked.

Related

Firebase database call working even when Authenticated user is disabled

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.

Flutter - Understanding Firebase Admin and how to get a user's information from email/uid/name

I'm making a little Snapchat clone, and a part of this app I'm trying to build is the ability to add a friend and start a conversation with them. I'm using Firebase to manage my users and I'm a little stuck now trying to figure out what works and why I'm getting problems trying to use some methods or functions.
What I want is this simple line of code to work:
var userByEmail = await _admin.app().auth().getUserByEmail("b#gmail.com");
print(userByEmail.toString());
However this has been giving my some problems, most recently, the following error message:
Unhandled Exception: FirebaseAuthError(auth/invalid-credential): Must initialize app with a cert credential or set your Firebase project ID as the GOOGLE_CLOUD_PROJECT environment variable to call verifyIdToken().
Getting to this point made me want to first ask a question about FirebaseAdmin and Auth before continuing and potentially screwing up my app settings.
Is there a simple way to do what I'm trying to do?
I have a Firebase.instance.initializeApp() in my Main function, do I only ever call that once or should I start initilizeApp in the initState of each Stateful Widget where needed?
What does this error message actually mean?
You are trying to use the Firebase Admin SDK in your Flutter code, which is not possible. The Admin SDKs give full administrative access to your Firebase project, which would be a serious security concern if you allow that in your Flutter app.
If you want to allow certain administrative functionality in your application, you will have to make that functionality available yourself. For example, to look up a user by their email address, there are two common approaches:
Store the minimal information about each user in a cloud-accessible database (such as Firebase's Realtime Database or Cloud Firestore) when each user registers with your app, and then look it up from there.
Wrap the getUserByEmail from the Admin SDK in a custom API that you make for yourself, on a server you control or in Cloud Functions. In that API you validate that the user making the call is authorized to do so, then call Firebase through the API you were trying to use, and return the minimal result back to the caller.
Both of these are feasible and can work to solve a variety of use-cases. But if you've never built backend code before, you might find the first approach easier to get started with.
Also see:
How to get Firebase UID knowing email user?
Flutter get User Data from Firebase
The right way to do what you want is using Firebase auth, authenticating your user and using a collection to store and retrieve users information. That auth information provided by firebase should only be used for authentication and security purposes.
The Firebase admin must have a user logged in to work properly, but its purpose is to provide a more administration environment and should not be used inside a clients app, unless its an admin app.
With all that said, lets go for the rescue:
Authenticate your user (using firebase auth);
After auth, save all the user information you want to share with other user inside its own collection (you will need to create one);
When an authenticated user (this is important) 'request any other users data, you query for the data in the previous created collection.

firebase firestore audit log in functions

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

Firebase Firestore Web SDK cannot seem to connect when user is logged in

I have an odd problem, which I'm hoping is either a misunderstanding on my part or a misconfiguration somewhere.
I am trying to use the Firebase Firestore web sdk to retrieve data. When I make read calls to Firestore in my webapp as an un-authenticated user, the reads return fine, as expected.
However, when I'm logged in as a user (either email/password auth or Facebook auth), I get an error:
Could not reach Firestore backend.
When I set the logging level to debug, I see this:
Firestore (4.8.1) 2017-12-24T01:08:15.146Z [PersistentStream]: close with error: FirebaseError: [code=unknown]: Fetching auth token failed: Cannot redefine property: refreshToken
Which seems highly related.
Has anyone else encountered this or have a sense of what may be going on?
Thanks!

Cloud Functions for Firebase: How to read/write to database as an existing user?

I like to use firebase functions to test firebase rules I defined.
I would like to read/write to realtime database as an existing user to test if the rules work as expected.
I read in getting started page, I can write to realtime database as admin as follow:
admin.database().ref('/messages').push({original: 'some text'});
How can I do the same as a user I have created in firebase instead of as admin?
I believe when you get the Delta Snapshot from the triggered event that the current state of that snapshot is tied to the user. Since the Firebase team is providing you with the server-less environment, they attach the admin as well since it's in a secure location.
So just grabbing the ref from the current snapshot, should give you the ability to test the database rules. Just to clarify, I am talking about the snapshot.ref, and not the snapshot.adminRef.
Here is the reference from their documentation:
Returns a Reference to the Database location where the triggering write occurred. This Reference has the same end-user permissions as the client that did the write. So, if an unauthenticated client did the write, this Reference is unauthenticated. If the client that did the write is authenticated as a certain Firebase Auth user, this Reference is authenticated as that same user.

Resources