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.
Related
I'm implementing an application that using Google Firebase Cloud Firestore. Because my application has a lot of small write requests, it will be very costly if I use Firebase Cloud Functions in the middle. Therefore, I asked a question on Should we allow users to write to database directly. All responses said that I should not do so. Then, why does Google Firebase Cloud Firestore has "write", "update" security rules? Users should not write to the database anyhow.
EDIT (responding to DIGI's comment & answer):
From the answer, it seems like we can use the firebase rule instead. Then, how should we correctly use them?
For example, my app is recording user's location when they turn on the map & update it to the database so that user's friends can see it in real-time. How should I ensure that the data is in the form {longtitude: double, latitude: double, timeStamp: TimeStamp}, and the user doesn't change any other few in the document?
This is a common misconception from standard MySQL databases and similar where a server acts as a layer of logic and sits between the client and database.
Firebase still has this layer of logic in a simplified version known as security rules which allow basic read and write operations from the client. The design is by shifting computing power from the server backend onto the client instead, saving in server computing costs on their backend by distributing that requirement to users' devices.
The concerns listed in SE are from people who are unaware of the limitations and restrictions you can place inside rules and your project to control what can be requested with firebase and your app.
To clarify, Firebase does not hide your database keys, they are easily accessible and yes, a user can theoretically make a client using your database backend. but so long as rules are in place, conditions defined, Cors configuration, and app origin settings are enforced, you can prevent all of this.
For multiple writes, Realtime is ideal since it can handle data faster and more cost-effective than Firestore writes.
So my example will respond with the intent of realtime database per your edit.
{
“rules”: {
“location”: {
“$uid”: {
“.validate”: “newData.hasChildren(['longtitude', 'latitude', 'timestamp']) &&
newData.child('longtitude').isNumber() &&
newData.child('latitude').isNumber() &&
newData.child('timestamp').val() <= now”,
}
}
}
}
I highly suggest getting familiar with some core concepts
https://medium.com/#juliomacr/10-firebase-realtime-database-rule-templates-d4894a118a98
Full documentation here: https://firebase.google.com/docs/reference/security/database
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.
I can't see much online as to whether it's possible to upload data to Cloud Firestore via Windows Powershell, I know you are able to upload data to the Realtime Database fairly easily, but is this possible for Cloud Firestore?
I need to be able to authenticate a user for upload to follow the database rules and upload rather than using the service account key?
Thanks for any answers or advice you may be able to provide me with.
If you are asking if there is a similar mechanism as the Firebase CLI for reading and writing data to Firestore as there is with Realtime Database, the answer is no, there is no provided tool for that. It currently only provides a mechanism to delete data.
You are certainly free to write your own program using the JavaScript client libraries, which have limited support for Firebase Auth and Firestore on nodejs. You can then invoke your program on the command line. You could also use the REST APIs for both products to write something in any language you want.
Can somebody else get the Firebase credentials from my APK and use them? Is this prevented by adding the SHA-1 keys for Android?
If it is prevented, what do I need security rules for since only code from my app with my SHA-1 can manipulate database at all?
If it is not prevented, can somebody else use my Firebase database as long as his requests fit the security rules? (Write 2nd client, which actually cannot do bad things but should not be allowed at all.)
Im not sure how I should think about security rules:
A) Protecting data against access and manipulation from bad guys + B?
B) Just a set of rules to keep data in a certain state and prevent my software from doing invalid database request?
A Firebase Database can be accessed via the REST API, or any of the client libraries. The decision about whether a client can or can't do something is entirely based on the rules.
You can even just access the Database URL in a web browser and see a JSON response by putting .json on the end, e.g. https://[YOUR_PROJECT_ID].firebaseio.com/.json
So the answer is definitely B! The default rules in a new Firebase project are that read and write to the database require auth, but you can configure them to provide whatever levels of protection you need.
Take a look at the Database Rules quickstart to see what you can do!
We don't ship the Realtime Database secret (or any other "secret" material) in the json file that gets baked into your app. That file simply contains resource identifiers that allow us to know which resources (database, storage bucket, analytics, etc.) to properly authenticate to (we use Firebase Authentication for these purposes), and we handle server side authorization to ensure that users are properly logged in.
If you are authorizing your requests properly (using Firebase Realtime Database Rules, for instance), your data is secure!
I'd recommend watching The Key to Firebase Security, one of our I/O talks, which talks in greater detail about how this works.
firebaser here
Thanks to the new feature called Firebase App Check, it is now actually possible to limit calls to your Realtime Database to only those coming from iOS, Android and Web apps that are registered in your Firebase project.
You'll typically want to combine this with the user authentication based security that Mike and Ian describe in their answers, so that you have another shield against abusive users that do use your app.
How would you use Firebase's simple login to allow users to upload music files.
As I understand it, it doesn't make sense to even think about storing audio files in Firebase's database which is why I would like to be able to store them on an external PHP server.
So, the question revolves on whether I can use Firebase's simple login system to allow users to authenticate to an external server.
I have seen Using NodeJs with Firebase - Security ... which gives some great insight, but then how would you enable the large file upload to the external server?
The technique from the answer you linked will work for your situation too, you just need to translate it into PHP and the Firebase REST APIs. Additionally, since the REST API isn't real-time you must add some kind of task queue that it can poll.
Your program would flow something like this:
User logs in to Firebase with Simple Login
User write to only a place that they can (based on security rules). The user also writes an entry into a task queue.
Your PHP server connects with a token that allows reads of all of the user's secret places.
Your PHP server polls the firebase every once in awhile to look for new tasks. If there's a new task, it validates the user and allows that user to post data to it.
All that being said, this is going to be pretty complicated. PHP's execution model does not lend itself well to real-time systems, and
I strongly recommend you consider some other options:
You're using a cloud platform, Firebase, for your realtime stuff, so consider a cloud service for your binaries too, like filepicker.io
If you really want to host the files yourself, use something that's more real-time like node.js. It'll save you the effort of constructing that task queue.