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

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.

Related

Where to store Google Service Account Key while using Google Firebase Functions

Using Google Firebase Functions as a backend of the small application.
Functions are accessing to the Firestore and Realtime database, therefore they need service account credentials file.
On the other hand, I'm trying to automate the deployment of the functions using Github Actions.
Currently I places the credentials file inside the repository. I know that it's not secure.
What is the proper way of storing service account credentials file in this case?
Firebase projects, are, in effect, Google Cloud Platform projects.
More specifically, when you create a Firebase project, an associated Google Cloud Platform project is created for it.
Therefore the process for storing credentials is the same as in Cloud Platform, which is to say in a file, somewhere relatively safe.
This file should be accessible to your Function if it is required, and should either have its path specified as part of an environment variable or explicitly declared in code.
You are already storing it the proper way, because the improper way would be to insert the contents of the JSON file directly into code.
To prevent others from seeing the contents of the JSON file, simply set the respository as private.

Firebase Storage clone uploaded file and create new file without downloading/uploading possible?

let's say I have an image /path/image1.png in the firebase storage. I want to copy this image and create a new image with a different name but the same content as /path/image2.png. I'm using AngularFire. How will I achieve this? Please help
Firebase Storage (nowadays called Cloud Storage for Firebase) is a set of client-side SDKs that allow you to access Cloud Storage from within your application.
There is no Firebase API to create a copy of a file in Cloud Storage. It's a valid use-case though, so I'd recommend you file a feature request for it.
In the meantime, the two options I can think of are:
Read the data to the client, and write it to the new location. This is definitely wasting bandwidth for the client, so I'd only consider it if your files are quite small, and your clients have a decent connection.
Use one of the (non-Firebase) server-side SDKs for Cloud Storage to create a copy of the file. For example, you could wrap this Node.js code in a callable Cloud Function and then call that from your application code.
await storage
.bucket(srcBucketName)
.file(srcFilename)
.copy(storage.bucket(destBucketName).file(destFilename));

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 Storage rules that query data from Firestore

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.

using cloud firestore and cloud functions within unity app safely

In my Unity project, I'm using simple web requests (POST requests) to store and retrieve information from the Cloud Firestore, and it is all working fine.
The POST requests are made to some Cloud Functions that do all the job in the database.
The thing is I'm using the database with all permission (read and write) granted to everyone.
I don't know how to safely allow this operations. What I mean by this is if I'm an user of the app (and I'm INSIDE the app), then I should be able to read and write from the database, but outside the app nobody should be allowed to do any modification in the database.
How can I secure my database within these constraints? I read about Firebase auth but I didn't understand.
You'll need to learn about Firestore security rules. It's a long and complex topic, and impossible to say for sure exactly what's required for your case. But you can start reading the documentation about it.

Resources