RTDB Allow read only if certain items in data - firebase

I have a RTDB in firebase in which I have a users subset. I currently have it configured to authorized users can make read requests, which I am fine with. However, I need to make a read request on a subset in my database (username in my users) allowed always, and another subset not reading but saying true or false based on whether a given email is in the users object (allow read but only for comparisons?). I am not sure if this is possible in firebase.
I am sending REST requests to the service as: "myfirebaselink/users.json?only="username", but this does not work.
My database structure:
users ...
{uid} ...
email
username

Related

Does createCustomToken(aUID) logout users currently authenticated with that same aUID

TLDR; Can multiple different users be authenticated and retain authentication via a generated custom token IF that custom token for each of those users is being generated always by the same UID? That is, User1 gets custom token generated by UID1 (via createCustomToken(UID1)) and then signed-in with signInWithCustomToken(), THEN User2 gets and signs-in with custom token generated using UID1, then User3 same thing etc etc, can ALL these users happily remained logged-in and experience no interruptions despite these other users being authenticated in this identical manner?
Long Version:
Ok, so I am trying to create a link-sharing system wherein a user who navs to this link can access a specific subset of my project's Firebase resources.
I have already tried using Firebase's signInAnonymously() to do this, but I dont like the way that Firebase does this for a whole host of reasons I dont want to get into.
The way i want to accomplish this is by:
generating a unique link (really a Firestore unique doc ID with some access data stored in that doc)
having the unauthenticated user navigate to some landing page, calling the cloud function and passing that unique link (lets call it a UID now)
cloud function, upon recieving this UID, will createCustomToken(UID), returning the token back to calling user
and the user will authenticate themselves with signInWithCustomToken(returnedToken) and access provisioned resources
Now, that is all well and good, but my question is:
If two (or any amount more people) people navigate to that same link and therefore pass and create token with the same UID, will they all be ok to continue happily using Firebase resources? Or is it because they got tokens created for them which utilised the same UID a sort of token-conflict is made, and therefore any next user who authenticates in this manner will revoke the previous user's auth token.
I havent been able to try this, and it seems like every question asked about these custom tokens relates to the generation and expiry time of them, which I understand. I wish the Auth docs were more clear on the mechnics and pitfalls of using Custom Tokens. I also havent been able to try it myself as it would be quite alot of refactoring, and was hoping someone could give me a straight answer to this.
Yes, a user can login on multiple devices without affecting other sessions at the same time irrespective of which auth method you use.
I'm not sure what the unique links are but it's not a good idea to pass the UID itself around if you function just takes a UID and returns a custom token as UIDs are pretty short and just a random string. It might be best to add a custom signed JWT in the links that contain the UID in payload so you can verify them before creating Firebase Custom Tokens.

can i make a firebese model that has a user and the data of that user with authentication in that same document?

I am trying to make a db model on fire base but I didn't understand the user authentication quite yet in mongo db you can make a document that has all the user data like email for example and passwords in addition to that user data, but in firebase the user authentication is a separate data base , can i make users document that include users data and authentication with in the fire cloud db ? or at least can I connect AUTH and db together ?
Firebase Authentication handles everything from hashing passwords to storing credentials and you don't have to store anything in a database. It also generates a unique UID for each user that can be used to identify user specific data in a database.
For example, if you have a collection "posts" then you can store the author's UID along with post data.
Also check: Firestore data modeling with more than one collection for each user

Do users need to create an account to read/write to Firebase

I'm making an app that has Firebase as its database. The app shouldn't need the user to create an account to use it, but I want the user to be able to read/write their data onto the database (so maybe they have to create an account?).
Do I have to make the users create an account in order to use Firebase?
My problem is that my security rules are read/write are allowed for everyone (which I know is wrong, but how do I change them and not need users to create an account?) Maybe that's the issue.
It is best to ask them to create an account
Although:
it can be a non-real email address and
there is anonymous auth also available
It sounds like you need the app to remember that user's particular data, so that when they return to the app, it is still their data (and not someone else's) that is being accessed.
To achieve that, we need each person's data to be stored in a different place in Firebase. Traditionally, this is by having them log in to some kind of system, most conveniently Firebase itself, and then the data stored in a branch of the database defined by their user Id.
Without logging in, you could simply ask the user for an identifier, such as "Bob" or "Carol", and then store their data under their identifier. The Firebase database would therefore have the following structure.
users/Bob/highScore: 3000
users/Bob/level: 7
users/Carol/highScore: 5050
users/Carol/level: 9
However this is not secure because there is nothing stopping Carol coming to the app and saying she is "Bob". Any such client-side activity you carry out to attempt to identify the user is not really authentication (in the opinion of Firebase) because all client-side activities can be faked relatively easily.
Firebase Authentication
The standard solution is to use Firebase to authenticate each user (see the Firebase authentication docs for this), and give your app a user Id (such as "8769dsg6f8g7698769876sdgs9") which is unique and known (by Firebase) to be correct.
Firebase security rules
You can then lock down the database using Firebase Security Rules so that only user 8769dsg6f8g7698769876sdgs9 can write to any of the users/8769dsg6f8g7698769876sdgs9/.... part of the database.
If you don't use Firebase to authenticate the user, Firebase will treat the user as unauthenticated and you will have no way to restrict each user to their own section of the database. Either you leave it wide open (to hackers etc!) or users will not be able to access their own personal data on it.
They can use a FAKE email address and password
If your concern is that they won't want to give out their real email address, you can ask them to make up any email address, e.g. mickeyMouse49857430679304#hotmail.com, and set a password. There is no obligation on your app to contact them on that email address or verify that the email address is correct.
Whenever they come back to the app, or access it on another device, they need to remember the fake email address and password.
Of course, if they lose their password, there is no way to reset it.
Anonymous Authentication, but at risk of losing access
The legendary Frank von Puffelen of Firebase, himself, has added a remark about Anonymous Authentication, in the comments below. From what I understand, this avoids them having to make up a fake email address.
I think the weakness of this is that if they lose their local web storage (e.g. if they manually wipe it, or move to another device), there is no way for them to re-access the same account, unless they have planned ahead by adding an email/pw to the anonymous account.
The only real way to have security per-user data storage is to use Firebase Auth to sign in the user, and write security rules to protect the database so that each user can only access their own data. There are no secure alternatives to this for Realtime Database.

how do you search/access users data?

I want to alert users who are registering that their choice of email address is already in our userbase; how can I compare their (desired) email to the users in my user list before (while) they register? Where exactly are the users stored and how can I access taht datanode?
You should have a users node that contains your users and other info about them.
Login credentials are stored internally in firebase so you don't have direct access so them. Having a users node allows access to other data about the user (and can double check to see if an email address is already in use).
users
uid_00001
name: "Frank"
email: "frank#wazmo.com"
fav_movie: "Airplane"
uid_00002
name: "Kato"
email: "kato#yipee.com"
fav_movie: "Pink Panther"
Using the above structure, you can simply query for the email address and if there's a match don't allow them to use it.
This is very common practice and there's a lot of information about handling users on the Firebase website.
Check out Storing User Data in this link
https://www.firebase.com/docs/ios/guide/user-auth.html
Note: 7 years later... When attempting to create a user with an email that already exists, Firebase will return an error indicating the email is in use, to which you can handle the error in that fashion.
That's probably a better option than querying a users node per above as that would require giving access to it for unauthenticated users.

Using field in Firebase security rule that is not stored in data

We are using Firebase custom authentication and want to define read/write access rules based on the "auth" payload data. However, for security reasons, we do not want to store the value of auth.uid anywhere in Firebase data. That is, since the user id for example is not part of the data, I cannot use the rule:
auth.uid == newData.child("userId").val()
Is there a way to just pass data to Firebase only for checking in the security rule, but not actually persist the data in Firebase db?
There are three possible sources of data for security rules: Hard coded strings, the database data, or the authentication token (i.e. auth).
You can generate your own authentication tokens, allowing you to specify any information you would like, without storing it in Firebase. Note that the contents of the security token cannot be forged by the user, but they can be read by the user; if your goal is to store some secret info users should not know, this isn't an option.
Note that you can secure any path in the database, so that it is not readable, store data in it, and security rules can still reference that data. Keep in mind that security rules cascade, so you want this data in its own path with no readable parents.
The security token mentioned in your comments sounds completely redundant of the user's auth token. If they have authenticated, you have already verified their uid, so it's unclear why a security token adds any additional value.

Resources