Can I set Firebase Database rules based on Instance ID? - firebase

I am new to Firebase Database and I am not planning to use the Firebase Authentication.
Is it possibile to set Firebase Database rules based on the Firebase Instance ID, rather than on the authenticated User ID ?
This is the structure I am thinking to implement:
/instanceIDs
/iid1
/somedata
/someotherdata
/iid2
...
/iid3
...
and I would like to restrict read/write permission only to that specific instance ID
anyone can show how to set such rule?
Otherwise, if I set read/write to true for all users, what is the security risk?
If my native mobile app code only reads/writes on the specific instance ID branch, can I expect some security issues?

The Instance ID in an app that uses Firebase Cloud Messaging identifies the installation of that specific app on that specific device. This value is not available in Firebase security rules.
While it sounds like an interesting idea to secure based on this instance ID, it would in longer term not work. The Instance ID can change over time, and every time that happens, the device would lose access to its data.
Access to Firebase (database and storage) is typically based on the user of the app. Unlike the Instance ID, the user's ID is stable over time: meaning that the same user will always have the same UID and thus have access to the same resources. If you don't want to ask your users to sign in, you can use Firebase's anonymous authentication.
PS: if you feel like experimenting with using the Instance ID to secure access, you can easily pass the Instance ID to a server, mint a Firebase Authentication token from it (you could use Cloud Functions for this), and then use that custom token to sign in.

Related

How to restrict firebase storage files only for the paid user?

I have the file stored in firebase cloud storage. This file will only available for the paid user download.
How to set up security rules to allow the paid user to have read access to that file?
[Updated]
I use the cloud firestore to store user collection
Each user doc contain
uid
email
name
photoUrl
provider
status
stripeCustomerId
purchasedProducts << this is the array of product name
I can verify paid user by looking if the product exist in purchasedProducts array.
However, inside the security rule from Firebase storage, it seem I can't access resource (user collection) in there. Or am I missing something?
Thanks
There is no way to access Cloud Firestore from within the security rules for Firebase Storage.
That means the only ways to currently implement your use-case is to:
include the necessary information in the ID token of the user, as a custom claim, which is then also available in security rules.
include the necessary information about the user (probably their UID) in your security rules
Since the second approach requires that you update your rules for every paying user, it's not very common.
Setting a custom claim can be done through the Firebase Admin SDK, for example from a Cloud Function that triggers when you write their payment information to Cloud Firestore.
Once you set the custom claim it may take up to an hour before it's available on the client, and from there in the security rules. The reason for that is that the claims are included in the ID token, which only auth-refreshes once an hour. If you want to get the updated claims sooner, you can force a refresh of the user's profile on the client.
Another approach you can try is to delete a file right after it was uploaded using the functions.storage.object().onFinalize webhook - this is wehere you can access the database and check if the user was allowed to upload the file.
Even though it may look a bit 'hacky' at the first glance, this is really a precaution measure in the first place - the UI itself would restrict the upload for the "good" users. And for those who messes up with the source code and tries to circumvent the system, onFinalize would do the job.
You can access cloud firestore through the firestorage service security rules:
https://firebase.google.com/docs/storage/security/rules-conditions#enhance_with_firestore

How to allow user to create and switch between multiple accounts in Flutter?

I am trying to make a Flutter app where the user can sign in into multiple accounts (different email IDs) and can switch between them from the UserAccounsDrawerHeader. For example, in Gmail app, users can switch between multiple Gmail accounts. Is this possible using Firebase Auth for Flutter?
In the default scenario, Firebase Auth generally does not support allowing a user to be signed in with multiple accounts at the same time. If you want to add support, what you will have to do is use initailizeApp() to initialize a new App instance - one for each user account, and sign in the user to each one of them. You will then have to pass that app instance around to the other Firebase APIs to use that account for authenticated access (for example, Firestore queries).
To be honest, it's not clear to me from the provided APIs how to do that last part. but perhaps Firestore.getInstance(app) might do it.
In any event, it is not trivial to implement. There is not a simple configuration or trick that will allow multiple simultaneous sign-ins. Usually apps just make the user sign out, then in again with another account.

Restricting read/write to firestore based on android package name

I have a Firebase project which contains 3 different android applications. These 3 applications utilize the same data stored under Cloud Firestore. My problem is that some of the data is particular to a single app only while some documents contain data which is supposed to be read by two of the three apps. I need to write Firestore security rules to implement this.
Is it possible to restrict read/writes to a particular document based on the android package name without having to explicitly send data regarding the app-id in each request?
Is there anything else which can be used instead of the package name to uniquely identify the applications while adding firestore security rules?
So far I have been trying to restrict read and writes based on the kind of authentication used by the apps as one app uses only phone auth while the other uses both email and phone linked together. So if the email is missing but the phone is present, I know it's from the first app. Is there any better way to do it?
It's not possible exactly as you're describing. Security rules don't have any way of determining or limiting the origin of access. They just limit who can read and write what data, as determined by Firebase Authentication.
You can use the authentication provider of the signed-in user via request.auth.firebase.sign_in_provider, or any of the other per-user properties shown in the linked documentation. You can also use custom claims in request.auth.token to tag users with some privilege that allows their access to some data, which must be set using the Firebase Admin SDK on your backend.

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 auth, is the user uid security sensitive?

I was wondering if getAuth().uid is sensitive/private in anyway? I am planning to use it on a user post something like: post.created_by: getAuth().uid. This makes writing rules/logic a lot easier.
The other way is to use the push id when the user is added to the database, which I'm trying to avoid.
No its safe to use the uid and recommended, firebase uses auth to authenticate the user and the assign the uid to identify the user across firebase.
You will be using uid in your security rules and as well as to identify user info in your db records.
Manually creating another id will render the efficiency of firebase useless.

Resources