Hasura + Firebase: using the new "claims_map" feature in Hasura 1.3.3 to set default role - hasura

I am using this method to auth a Flutter app with Firebase. The gist is when a new account is created, a cloud function is run to apply the claims to the new Firebase user account so Hasura can use them. The issue is this happens 1-10 (maybe more) seconds after the account has been created, so I cannot log them in for some arbitrary amount of time until the claims are applied.
I want to use the new claims_map functionality in Hasura 1.3.3 to apply default claims to a logged in user, to be overridden if a user has claims already in Firebase.
Since this feature is very new, does anyone have experience in setting this up?

You may have already answered this yourself. In case not, then if you have already set up everything according to those instructions, the only thing you need to do is add a line to HASURA_GRAPHQL_JWT_SECRET, maybe something like this:
"claims_map": {"x-hasura-allowed-roles":["user"],"x-hasura-default-role":"user","x-hasura-user-id":{"path":"$.user_id"}}
It just works.

Related

Firebase Auth UI - Sign in vs Sign up

In my Firebase web app, I offer 3 different authentication methods – phone, email/password, and Google.
When new users go through the FirebaseUI sign-in flow, sometimes they don't remember which method they signed up with originally and use a different method (which creates a new user). For example, they created an account originally using their phone number, but when they return later (unauthenticated, perhaps on a new device), they see "Sign in with Google" and try that option – which creates a brand new user/account.
They are then confused why their account state is blank/new.
Is there a way to define a sign-in flow as such, so that if a user does not exist, it should not create a duplicate account (or at least offer an option to link to an existing user)?
I'm using the FirebaseUI for simplicity and hoping there's a flag or something I can set in the config that will achieve this.
For example, they created an account originally using their phone number, but when they return later (unauthenticated, perhaps on a new device), they see "Sign in with Google" and try that option – which creates a brand new user/account.
That's normal behavior since you don't have any information that it is the same user. To solve this, you should collect the email address of the user first time he/she signs up with the phone number. In this way, you can check the second time, whether the user has already an account in your app by searching for the existence of the email, as explained in my answers from the following posts. That's for the Realtime Database:
Checking if a particular value exists in the Firebase database
And that's for Firestore:
Firestore query - checking if username already exists
Is there a way to define a sign-in flow as such, so that if a user does not exist, it should not create a duplicate account (or at least offer an option to link to an existing user)?
Yes, by getting specific data to recognize the user. You either get the email address, as explained above or you get the phone number if it tries to sign in the first time with Google.

How to save user data in db, without logging in?

I am working on a simple app that allows users to search for something using an API and save it to view later.
However, I don't want to integrate authentication in the app. I can, but would rather not as a UX decision. Do you know of a way to generate a device token, that is unique to every device and can be used to store which assets a device has saved in the db?
I am thinking of expo push tokens as a possible solution, but that would require users to accept push notifications - so what happens if a user says no?
Sounds like you could just use react-native-uid to generate a unique id for your device and then store it in AsyncStorage and fetch it from there going forward.
For more inspiration, or perhaps just a more canonical way to do this... read up on suggestions surroundings the recently deprecated constant for installationId here:
https://docs.expo.dev/versions/latest/sdk/constants
I haven't used this before but if you're looking for something bullet proof then this is probably your goal of getting the same concept.
Firebase Anonymous Authentication might be ideal to use in this case. This can be used to create a user in Firebase auth without any credentials and can be useful especially when you are using either of Firebase's databases since you can use security rules with user's UIDs.
However, once the user logs out of the account by any means including but not limited to using sign out option in your app, clearing app data or uninstalling the app, the same account with that UID cannot be recovered. I looked up for AsyncStorage and apparently that gets cleared to if the app is deleted.

Get origin for newly created user on firebase auth trigger

Is there a way to know if a newly created user was done so using the client or admin SDK?
No, the auth trigger isn't origin specific. It doesn't care how a new user account gets created... it doesn't get called/triggered until the creation occurs.
Not to go too far off topic from your question, or turn this into a fully-fledged conversation, but what are you trying to accomplish that you want to detect what created the account? I feel like there's probably a different way to handle the scenario you're facing.

What happens to Firebase anonymous users?

I want to know what will happen to the users of my app that I used anonymous sign in method for them.
The Firebase documentation is really BAD and didn't explain everything and expect developer to find out himself.
I found in its old version documentation that anonymous session will expires based on the expiration time has been set in Login & Auth tab, but even there didn't mention this means just the session ends or it means that user id will remove also from my app users list or what EXACTLY happened?
I found this answer but it really is not acceptable. The number of anonymous users will grow very very fast if you do a web app and make every thing hard.
I even cannot see the number of my app users in my dashboard!!!!!
So, what should i do? should i develop a dashboard for my data myself or Firebase team should do it? At least for managing users i should have more power than just searching user with their email and when you use custom login you cannot do this also.
Anonymous users don't expire, and there isn't currently any automated way to purge them.
Firebase doesn't automatically remove them because it doesn't really know if a user is still storing data linked to that login - only the app creator does. Imagine if you are playing a puzzle game on your phone, and get to level 100. Then when you go to play level 101 next year, all progress is lost. Firebase can't just assume a user being inactive for a year means that the account can be removed.
There is a couple tools that should help, though.
1) Admin SDK & Firebase CLI list users.
2) Linking multiple auth providers
3) Auth State Persistence
Once you list your users, you can check that each doesn't have any other providers, and hasn't been used recently, doesn't have data stored, and delete them.
Better, though, would be to ensure that only one account is created per user. If you create an anonymous account to help users store data before logging in, you may want to consider prompting them to link a auth provider (like Google or email). If you link the account, rather than creating a new one, you'll avoid abandoned accounts from active users.
In general, you will also want to make sure to use auth state persistence to ensure that there aren't more accounts than necessary being created. Creating 1 account per new visitor, rather than 1 per time someone repeatedly visits your page, will significantly help keep user growth in check.
In my case, I am using the anonymous sign-in method for authentication without the knowledge of the user.
Each time when the user leaves the app, delete the anonymous user by -
FirebaseAuth.getinstance().currentuser?.delete()
There will be no stacking up of anonymous user with this and limits the number of anonymous user in the app
2023 update
Firebase has automatic clean up now.
If you've upgraded your project to Firebase
Authentication with Identity Platform, you can enable automatic
clean-up in the Firebase console. When you enable this feature you
allow, Firebase to automatically delete anonymous accounts older than
30 days. In projects with automatic clean-up enabled, anonymous
authentication will not count toward usage limits or billing quotas.
Any anonymous accounts created after enabling automatic clean-up might
be automatically deleted any time after 30 days post-creation.
Anonymous accounts created before enabling automatic clean-up will be
eligible for automatic deletion starting 30 days after enabling
automatic clean-up. If you turn automatic clean-up off, any anonymous
accounts scheduled to be deleted will remain scheduled to be deleted.
These accounts do not count toward usage limits or billing quotas. If
you "upgrade" an anonymous account by linking it to any sign-in
method, the account will not get automatically deleted. If you want to
see how many users will be affected before you enable this feature,
and you've upgraded your project to Firebase Authentication with
Identity Platform, you can filter by is_anon in Cloud Logging.
Docs
There is a possible cloud function for that.
Check: delete-unused-accounts-cron
This function deletes unused accounts after a certain time. Which might be also helpfull for nonanonymous users.
If you only want to delete anonymous users or check only for them (for example delete after a different inactive time than normal users) you can identify them by checking:
const inactiveUsers = result.users.filter(
user => {
isAnonymous = user.providerData.length == 0;
//do something when anonymous
});
If you'd like anonymous users to be removed from your user list, you'll have to write a service to do that for you.
Since firebase doesn't provide a way to list registered users, you'll have to make sure you're storing some sort of user list in the database. You can then use the node.js admin sdk to get user data, check if the user is anonymous, and find when the user was created. For performance reasons, you may wish to store this information in a special area of your database and retrieve it all at once. Once you've identified a stale anonymous user they can be easily deleted.

Passwordless account generation in Meteor

I'd like people to be able to initially use a meteor app without explicitly creating an account until such time as they wished to share their data or see their data on another device. Even when they were happy to explicitly create an account, I'd like the option for that user account to be passwordless (i.e. https://passwordless.net/).
But I'm struggling at the first hurdle. How do I check that a user account doesnt already exist and create one if necessary?
There are a few packages which look promising:
https://github.com/artwells/meteor-accounts-guest/
https://github.com/tmeasday/meteor-accounts-anonymous
If neither of those are exactly what you want then they should at least provide a good starting point.
An alternate would be to use accounts-password and automatically create a unique user account for the guest once they perform some important action so you can store their data. Store the login credentials for that account in localStorage (or a cookie). Then once they are ready to signup, move their data from their temp account to their real account and delete the temp one.

Resources