Firebase Storage rules that query data from Firestore - firebase

I need to check a document's data in Firestore to allow someone to view an image in Firebase Storage. Is this possible?

It is currently not possible to access Cloud Firestore documents directly from Cloud Storage rules. You have two options:
Somehow use Firebase Authentication custom claims on the user account to determine if a user should be able to access a file.
Use some backend code (maybe a Cloud Functions HTTP trigger) that the user accesses to download the file if the conditions are met.
In either case, you will need some backend code that checks and sets the appropriate data.

Related

How can I upload files to Cloud Storage through Cloud Functions and use Firestore to control access to Cloud Storage?

I'm trying to implement a system that allows react-native clients to upload files to a specific folder in Cloud Storage and allows clients to download from them. I can't do this directly from the client because I first need to query Firestore to validate that the user is 'friends' with the owner of the folder which will allow for read/write permissions.
I decided to use Cloud Functions as a middle layer to encapsulate this business logic and I expected to also be able to use it as a middle layer to upload the files. However, I feel like I may be misunderstanding how to best use these services together to solve this problem.
Current Plan:
Client uploads file to Cloud Function (assuming they are permitted after Cloud Function queries Firestore and validates)
Cloud Function uploads file to Cloud Storage
Client can then request file from Cloud Function, which validates permissions using Firestore and downloads file from CloudStorage
Cloud Function sends file to client
Questions:
Can/Should I use Cloud Functions in this way as a middle layer to upload files after validating permissions store in Firestore?
Is there an alternative solution using firebase that would mitigate the 10MB download limit with Cloud Functions but still allow me to authenticate uploads/downloads to and from Cloud Storage using my custom business logic on relationships in Firestore?
Any help or guidance here is appreciated! I'm very new to firebase, cloud architecture, and architecture in general.
This is definitely a valid and technically feasible approach. Whether you should do it, only you can determine of course.
An alternative is to use Firebase Storage's security rules to enforce the access control on the files. But you won't be able to read anything from Firestore in those rules, so you'll have to ensure everything needed to grant/deny access is in the path of the requested file, in the file's metadata, and/or in the user's token.
Even if you implement the download of files in Cloud Functions, you can still perform uploads through Firebase. You could in that case for example have the user write to a temporary location, which then triggers a Cloud Function that can do whatever additional checks you want on the file.

Firebase storage security rules: Is it possible to use firebase database collection fields value in security rules? If not how can I solve this issue?

I have migrated data to firebase storage, which have structure like:
<fileId>/<filename>
I can store fileIds associated with user in firebase database like:
<userId>/<fileids>
Is there anyway I can get something like auth.uid/fileids from firebase database in security rules of firestorage, to only allow to read file to auth user, if fileIds belong to him. If not, what all options are available to achieve the same and which one is best among them?
It's currently not possible to use data from databases in your Cloud Storage security rules. You can only use information about the object stored in the bucket.
You could instead write a backend API that performs all the checks and then operates on the object in storage, or store information about the file in its metadata for use in rules.

How do I authenticate Firebase functions/admin requests to Firestore

I was able to complete the process of generating a Firebase auth token on the front end, sending it to a Firebase Cloud Function, and using auth.verifyIdToken to decode it and pull out the user ID.
I want to use Cloud Firestore, but I have no idea how to use the user token/ID when making requests to Cloud Firestore from Firebase Functions. My goal is to then have those variables available when creating Cloud Firestore security rules.
a) Do I need to pass those variables in the Firestore request?
Example:
postsRef.where({uid //somehow?}, 'published', '==', true).get();
b) Should I use auth.setCustomUserClaims? Is that the only option when working from the Admin SDK?
c) What is different in usage between the ID and the decoded token? Should I pass both to Cloud Firestore? Is that even possible?
Let me know what you think, any info is helpful.
Thanks,
What you're trying to do is actually not possible. When you query Firestore from backend code using one of the server SDKs (including the Firebase Admin SDK), the query will always bypass all security rules. There is no way to change this behavior. Rules only apply to direct access from web and mobile clients.
What you'll have to do instead is duplicate the work of the rule in your backend code to make sure all the conditions are correct before making your query.

Firebase Storage allow write to folder to multiple users

I have created an app, that allows users to create a simple photo collection. All the data is stored in the Firebase Cloud Firestore. The images are uploaded to Firebase Storage.
The owner of a collection can invite any other user to access his collection and upload photos.
The sharing of data in Firestore works fine. But now I have problems with writing the security rules for Storage. Does anyone know, how I have to write the rules, so that any user added to the collection can access the images as well? The files for each collection are stored in separate folders.
Firebase security rules currently do not bridge between products. You can't use data in Cloud Firestore in security rules for Cloud Storage. The only things you have access to in security rules for Cloud Storage are object metadata and Firebase Authentication custom claims per user. You will have to figure out a way to make changes to either one of those things to implement your permissions.
Alternatively, you can direct all access through Cloud Functions to decide if the user should be able to access the content, but bear in mind that Cloud Functions responses can only be 10MB maximum.
You should look into creating a private group and authenticate the group with help of private token.
https://firebase.google.com/docs/storage/security/user-security#group_private

Firebase rules: is it possible to communicate between security rules of different products

I understand that I can specify rules for some features in firebase like real-time database and firebase storage.
Example:
I can specify a rule in real time database that allows only users to update their data under their specific UID.
Question:
Is it possible to specify a rule in firebase storage such that a user can download a file (ex: image) if and only if he exists under a certain node in the real time database?
Is this communication between security rules of different products possible?
If no, what can I do?
Thanks.
You can't communicate between products like this.
What you can do instead is use custom claims on authenticated user profiles to control who can access what locations in various products.
Read more about custom claims here.
Read more about realtime database rules with custom claims. Read about auth.token.
In Firestore, you can use request.auth.token to access custom claims.
In Cloud Storage, you can also use request.auth.token.

Resources