Separate Users and Sellers in the same app with same Firebase in Flutter - firebase

hope you are well
I am trying to make an app where from the same app, you can either be a user or you can be a seller. In our case, the seller will be a restaurant and the User will be a restaurant-goer. My problem is that if I log in the "I am a restaurant login"-not a user login. On restart the app auto logs in and takes the user to the User homepage, not Seller homepage, as I am using the
auth.currentUser != null ?
Then add the home screen or login screen depending on auth state, but it is a general auth state. How would I make it show a different home screen based on the type of Logged in user. So I know why it takes me to the User homepage-I set it to do that, how would I make it takes me to one or the other
thank you

Firebase Authentication has no built-on concept of a type of user, so you will have to build that on top yourself.
You can store the user-type in the user's profile as a custom claim, or in a cloud-hosted database. In either case, you should do this from a secure environment so that user's can't change their type (unless your use-case specifically wants them to be able to).
So with that out of the way your app then takes these steps when started:
signs in the user, or restores their auth state.
determines their type.
redirects them to the correct screen.
Also see:
the links for How to create two types of users(Client , Freelancer. for example) while Auth using firebase in a flutter app?
How to create 2 different User group in Firebase AUTH with Flutter
many more results from searching for [firebase-authentication] two types of users

Please post the code you are using for this pathway.
I would advise you to create a property called userRole, and store this when the user is created.
When you send their name and image and email to Firebase after successful auth, store with that info their userRole.
In your widget tree, I'm assuming you have two widgets, CustomerHome() and RestarauntHome(). Now, after successful login, pass the user info to this widget, and check:
user.userRole == 'restaraunt' ? RestarauntHome() : CustomerHome();
This way, when they come back to the app, the page they are not allowed to see, will not be displayed.

Assuming you are using firestore database to manage your users' data, in the document of the users collection you can add a field of role whose value could be user or seller. Write to this field when a new user user/seller signs up. Then in the home page, return seller homepage when the value is seller otherwise return the user homepage. While the document is being fetched you can return the loading screen.

Related

How to create a Magic Link with Firebase to login a user instantly every time he use it?

What I want
I have a list of people with all their personal information (name, first name, date of birth, email, etc.). I created an account for each of these people using their email/phone + a password I generated for them.
I want to send to each of these people an email/SMS with a link allowing them, once clicked :
to be directly connected on our website, without having to type a password or using a third party as Google/Facebook/etc.
and I want the link not to expire after the first use. The user must be able to click on it several times and be connected to our website each time.
What I tried
This is what I tried so far, unsuccessfully :
Passwordless Auth with email link: using both backend and frontend. Doesn't fit my needs because the signin link works only once by design.
Create a custom token with Firebase: as I understood, the token will expire 3600 seconds after creation, which is not useful for me.
Implement anonymous auth: it still need the user to type email+password at some point if you want to convert the anonymous account to a permanent account (because I don't want to use Google/Facebook/etc auth). Plus, it will need consequent changes in all my website code to work.
At this point I realized that Firebase doesn't have a solution that fits my needs. I started to fiddled around as best I could.
The idea
It works as the following:
First I create an account for the user in Firebase + a unique document in a collection in Firestore. That document contains 3 fields: magic_token, email, password.
Then, I create a link to our website with a unique token as a parameter in it. I store the token as magic_token in the document I described above. I send the link to the user.
The user clicks on the link, get redirected to my website. In the front, I detect the presence of the token in the parameters of the URL, I retrieve the document in Firestore with the corresponding token.
Using the email and password stored in this document I call: signInWithEmailAndPassword() to login the user.
PROS:
it fits my needs.
it is easy to implement
CONS:
the user password is visible in Firestore.
it's not very secure.
The question
Is there a proper way to implement a Magic Link that fit my needs? If not, how can I improve my own custom token authentication ?

Have one user signup another user with custom fields in firebase/flutter

I am trying to determine if the following scenario is possible with flutter and firebase:
we have users within the company who will be given access to the app, where on the homepage will be a signup another user button where they enter in that user's email and password, they get signed up, and then the original user specifies custom fields for the 2nd user, such as company name, role, position, etc.
Is this possible with flutter and firebase?
Have asked the flutter google group and was told about custom authentications, but from what I see that is just an external authentication system and doesn't show me how to let one user create another users profile with fields.
Any ideas?
The first thing to consider is whether those properties need to be in the user profile at all. The user profile is sent with every request, and should only contain information that is relevant for securing access. If you have additional information to store about the user, you should store it elsewhere (such as in one of Firebase's databases) using the UID of each user as its key.
Assuming that the information is about security (such as the role seems to be, there is no secure way to let one user set security properties (typically referred to as claims) from client-side code. As soon as this is allowed from client-side code, anyone could set such properties for anyone else. That's why setting custom claims for a user is only possible with Firebase's Admin SDKs, which are designed to run in a trusted environment - such as your development machine, a server you control, or Cloud Functions.
There are a few other options, but it's important to realize they're all implemented on top of the above approach.
There is an experimental extension that allows you to set auth claims by writing a document into Firestore, which something like this (JavaScript syntax, but the Flutter code will be similar):
db.collection("user_claims")
.doc("abc123")
.set({
role: "admin",
groups: ["example1", "example2"],
});
Now of course you'll want to make sure that you secure writing to the user_claims collection, as otherwise you'll end up with the same security risk I mentioned in the first paragraph, where everyone can claim any role they want.
Alternatively you can write your own server-side API (for example on Cloud Functions) that you expose to your application, and that then calls the Admin SDK. Here too, it is important to secure access to this API, to ensure only authorized users can call it.

Firebase subaccounts

I'm currently building a POS/Store admin app, when a user gets into my app, the Owner of the store will then be asked to login only once for setup purpose (e.g. a new machine), the app will then display a list of staffsName that has already been added by this owner, and then everytime a staff wants to start a new transaction, he/she will only need to click on his/her name, then enter his/her 4-digit pincode to 'login' and process the transaction.
How do i go about achieving this?
I was thinking of using firebase auth for the 'login' of the staff, but then when i log in using the staff credential, I will lose access to the uid of the owner, which is needed to access the owner's store data such as his/her products.
i'm also thinking of using firestore to store the 4digit pincode, but then i'm also concerned about security
There are multiple ways you can approach this, one where you utilize the email login by simply appending a fake domain to the username to create a valid email domain. This user account could be the designated 'user' in question, or utilize credentials inside custom claims or hidden in a database that allows the client or server (depending on your preference) to then log in as the user.
Moreover if you want the manager to login once you can add Authentication State Persistence to specify whether a signed in user should be indefinitely persisted until explicit sing out, page reload etc.
Another approach requires the user also to have a valid auth that is not an email password and you link your pin auth to that main account with Firebase Auth Linking per the documentation: https://firebase.google.com/docs/auth/web/account-linking.
This does however require that the user be registered from an auth provider such as Google, Twitter, Apple, etc. then the user will have to activate this link by logging in for authentication purposes. This can in theory be automatically generated and processed without the user knowing.
It is a long way around it since this is essentially a custom solution but it does create the flow you are looking for without having to use a custom auth provider.

Firebase: should I store user data on the authentication profile or database

I signed up a user in my Flutter app using FirebaseAuth.instance.verifyPhoneNumber(). This works perfectly and the user shows up in my Firebase Console.
FirebaseAuth.instance.currentUser() now returns the user for me whenever I open the app. Should I store user info (age, weight etc.) here, or should I create a users collection in my Database and link the currentUser().uid in there?
Also, should I store it on the Database linked against the uid, or linked against the login info. For example, link a user to the phoneNumber and not the uid. Because if you ever delete the user, but they want to register again, then they will get a new uid, but their phoneNumber / email will still stay the same and can therefore still link to their old data.
You can't add arbitrary data to the Firebase Authentication user profile. So you should store the additional data in a database, and indeed associate it with the UID of the user, so that you can easily look it up. This also allows you to implement searches for users more easily, as the client-side Firebase Authentication SDKs have no functionality to look up data for any user but the currently signed in one.
To the additional question: if a user deletes their account from your application, you should respect their wishes and delete the additional data that you store for them too.

In meteor how to prevent social logins from creating an account if one is not available?

Currently, by default if I try to use social login in meteor, it will create a new account for the user if one is not available. But I don't want that. Here's what I need :
When the user signup, I need to provide social signup options. When the user signup with the social account, it should come back to the app where I will present the user with a form to enter extra details. I don't want to create an account until those details are filled. I will pull the name and email from social accounts.
At login, if the user have already connected a social account, he will be allowed to login. Otherwise he have to signup first.
How can I implement this behavior in Meteor?
The way I handle this is in Account.validateNewUser
this function validates the user and returns true or false.
but you can add logic to the process.
In my case, I check if the user exists by email:
social logins (except for Twitter) all create a user with email.
the function contains a user object parameter with the user account info
If you do a check using Accounts.findUserByEmail(<email>) you can find if the user has been created previously.
In that case,
there are 2 cases:
user tried to create an account with password, just return true and the rest of the user create process will prompt the user that a user already exists with this email.
if it's a social login, I merge the 2 user objects to make it one, keeping the original _id. then return 'true' to pass the validation process.

Resources