Firebase Function onLink trigger - firebase

Is it possible to implement a function hook on when an anonymous user is linked to a normal account?
What I am trying to achieve in a secure way is:
1. DeepLink for invitation opens in the app.
2. Get invited_by from the URL and sign in the user anonymously, saving invited_by to invitations/anonymous_user_1/invited_by.
3. User registers an account and signs in so onCreate function is triggered, but we do not have access to the anonymous account there.
4. If there already is an anonymous account before registering, we link the anonymous account to the users new account.
And here is where I want to trigger a remote firebase function (don't want to trigger it on the client side, because it could be retriggered and abused to gain invitation advantages).
onLink() should do something like this:
1. Get old account (anonymous) and new account.
2. Get invitations/anonymous_user_1/invited_by from anonymous account.
3. Store it and perform actions on the new account.
4. Delete invitations/anonymous_user_1/invited_by once processed.
Is there a way to do this server side? Because onLink() would only be called once, and therefore I could process the anonymous data once.
As I said I would not want to call a function locally.
Thanks

There is no Firebase Authentication trigger for Cloud Functions when a user links accounts from multiple providers at the moment. As Doug commented, it's best to file a feature request for this.

Related

Synchronize users created with Firebase Auth to my custom backend

I want to use Firebase Auth for my user login/registration process. Everything else should be handled by my own backend (spring boot app + postgres db).
Now I'm asking myself how I can synchronize a new created user to my user table in postgres. I thought about the following:
REST call through client - Everytime I get a success event from the firebase sdk I call an additional request to my backend which sends uid, username etc.
Problem: What if my backend call fails but the register process was successful ? That would lead to an inconsistent state since (at least thats what I understanded) I can't easily rollback. That would lead to situations where a user can login into my app without my backend knowing the user. This would crash/ invalidate all my following queries (e.g. search after user xyz would lead to no result even though he/she exists)
Check the existence of the user in the postgres database
Here I would query the uid from the database (which I got from the jwt) and create a new user if it doesn't exists in every incoming request.
Problem: The user query is a unnessecary overhead for every incoming request.
Trigger with cloud functions - When I understood it right firebase auth is firing events when a new user is created in cloud functions. This could be used to make the external api call.
Problem: I dont know what happens when my external rest call fails at this point. Can I rollback the registration ? Will I be ever catch this event again ? I also proably would have an eventual consistency situation, since I dont know when the cloud function triggers. Furthermore I would prefer not to include cloud functions to my stack
Is there any way how I could do this in a transactional manner ? Did anyone else tried is using sth simular ?
Thanks for every help!
The easiest way is actually to not synchronize auth data, but instead decode and verify the ID token of the user in your backend code.
This operation is (by design) stateless, although Firebase's own backend services often implement a cache of recently decoded tokens to speed up future calls with the same ID token.
Apparently, I finally came up with a different solution:
Register user per Firebase SDK (e.g. with email + pw method)
Make a post-call to my own registration api including the resulting uid from the previous step and some metadata
API creates a new user including a column with the UID + Fetches the firebase token of the user and adds an internal claim that references to the internal Postgres UUID via Admin SDK.
Frontend gets the created user and hard refreshes (very important, since the previously fetched token won't contain the newly added claim !) the firebase token and verifies that it contains the token. If it does -> everything is cool, if not some oopsie happened :) That will require a request retry.
Later when you start your app you can just check if the passed token contains the custom claim, if not open the sign up/sign in page.
Every endpoint except the one for registration should check if the claim is set. If not just forbid the request.
How to set custom claims:
https://firebase.google.com/docs/auth/admin/custom-claims#set_and_validate_custom_user_claims_via_the_admin_sdk
You can use the Firebase Admin SDK to create the user account from your back-end instead of from the client.
So first you create the user in your database, then grab the ID and use it to create a user with the same ID in Firebase.
If all goes well, send a confirmation to the client and sign it in using the same credentials they entered.
Why not creating an endpoint in your backend service and call this endpoint when a client side authentication succeeds?
This method should do 2 things:
decode token to get access to Firebase user object (Firebase Admin)
Compare Firebase user with your internal user table. if it doesn't exist you can create it using firebase user object, otherwise do nothing.
This solution allows you to do other nice things as well (Syncing user info between Firebase and your internal db, providing a way to let a frontend know if this user is new or not, ...) at a relative small cost (1 get call per sign in)

How to make firebase not create a new user for Google OAuth on sign in?

On sign in using firebase's Google OAuth provider, it automatically creates an account for the user if one does not exist. Is there a way to not create an account and return an error on sign in?
(https://firebase.google.com/docs/auth/web/google-signin)
When you call the sign-in method, it will create an account for the user if it does not exist.
If you want to check if an account exists or not, you would have to perform the "Login with Google" OAuth flow yourself (without the Firebase SDK) and then use a Cloud function to check if a user with the email exists (you might also have to maintain a list of users (their emails) in Firestore). If not, then you can create a new account with the access token you received.

Can you trigger (firebase) cloud functions on auth login (but not account creation)?

It seems like the firebase auth triggers are onCreate and onDelete. I'd like to also fire some kind of trigger on non-create login (basically periodically syncing the user's avatar and display name and such with what's in the database).
I can fake this by just doing it on the client side, which is what i'm doing right now - just updating the user record with whatever is in firebase.auth.user. Excitingly, this can't be done right after login, since if the login is also account creation, the user record tends to not exist (since it is created via a triggered cloud function), and I can't tell from auth.signInWithPopup() if the resultant signin was a creation or login event.
There is no such trigger. As you've observed, it just provides onCreate and onDelete.
Firebase Auth doesn't provide a way to sync the user's avatar with their authentication provider. It just copies the URL once at the time the account was created.
If you need to update the user's profile picture, you will have to do that yourself by calling updateProfile() on the user object and provide a URL for the picture.

Firebase: Implementing Switch / Add Account Features

I am working on Firebase application ( Firebase version 4.1.3 )
My health care related application is made for dependent group of people such as children and seniors. However, most of my users are independent group of people age around 18-55. Most of my users use my application for their seniors/children. They need to create account for each of their family seniors/children member. Therefore, my users have to log in and out many times and they have to keep track of their family members' account. My first thought was I should make an account switching feature so that my user can switch their account back and forth between their family members to update information on my application.
After searches on Google, I found way to force switching account on Firebase authentication with Google provider, but those are not what I'm looking for.
My questions are:
Is it possible to store the multiple firebase auth objects (logged in object) in client side?
If it is possible, for how long will the token inside the firebase auth object last for?
If it doesn't last forever, is it possible to refresh update the token so that it can be use without authenticating with the social/phone login again?
The functionality you are asking for is not available out of the box. You have to build it on your own. I do think Firebase provides the pieces to allow you to build it (via Auth and Database).
Is it possible to store the multiple firebase auth objects (logged in object) in client side: You can have multiple Firebase app instances and each one have an auth instance with a current user. You would need to ask each user to authenticate though (you can't authenticate once and sign-in into all of the account). However, you can build your own user group login mechanism, where logging in with one "master" account can allow you to login with multiple accounts using custom Auth.
If it is possible, for how long will the token inside the firebase auth object last for. Firebase sessions are supposed to be indefinite. If a token expires (typically after one hour), it can be refreshed automatically if you are using real time database.
I do not think Firebase has that token capability. But what you could do is simply put the email address of the people in the device by Shared Preferences( for Android). When the user wants to log in with that user bring the email address just ask him to enter the password and then go through the log in process. If you do not want to use SharedPreferences you could simply store the users(also as you said family members) in Firebase Database and link them with the controller user so to speak. Whenever user wants the switch, go and bring the email addres of other family members from Firebase Database and ask in the client for the password and do the login by Firebase Authentication.Hope that helps!

How many time Anonymous users are created in Firebase

I would like to use the signInAnonymously feature from firebase but I'd like to know how it works exactly.
Is this anonymous user added as any other user in Firebase (but without an email or password) ?
Is it automatically removed after a certain time ?
If I call this method on each app launch. Will it create a new user everytime ? How will it know how te reuse an old one ? Local Storage ?
So will it create another user in database if my users connects from another device ?
Thanks a lot
An anonymous user account is similar to any other user account in Firebase, except that there is no way to identify the user.
Anonymous users are not automatically removed.
Each time you call the API to create an anonymous user, a new account will be created. To re-use the existing account, you should listen for the auth state when the app starts and only create a new user account if the user isn't signed in yet.
If the same (anonymous) user signs in from multiple devices, they will get a separate account on each. If that is not what you want for your use-case, you should require one of the identified authentication methods (email/password, Facebook, Google, etc)/
Frank's answer to the third question is incorrect.
From the documentation:
If there is already an anonymous user signed in, that user will be returned instead. If there is any other existing user signed in, that user will be signed out.
Therefore, this method can be safely called every time the application starts.

Resources