How to access Firebase Database APIs? - firebase

So in firebase I created a database named crud.
Now database rules looks like this,
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Now I try to access the API with https://crud-12b8c.firebaseio.com/crud/users.json then I get 404 not found error. What am I doing wrong here? I am new to Firebase btw.

You are mixing up Cloud Firestore and the Firebase Realtime Database. firebaseio.com URLs are for Realtime Databases, but the console screenshot you're showing and the security rules you're displaying are for Firestore.
I'd recommend reading the guides about how to access data using the Firestore SDKs.

Accessing the firebase API is done through the Rest API service of which, you can find the full documentation here: https://firebase.google.com/docs/projects/api/reference/rest
This includes means of accessing Firestore data points directly through web requests:
https://firebase.google.com/docs/firestore/reference/rest/v1/projects.databases.documents/get
For example:
https://firestore.googleapis.com/v1beta1/projects/crud-12b8c/databases/(default)/documents/crud
It does get complicated but this is a great start to using Firebase per your needs.

Related

How to apply firebase storage rule so only Google cloud run API can write?

My goal is to block any write requests that don't come directly from my API in google cloud run.
I think my firebase Web API key from the general project settings could help but I can't find the right storage rule that can do this.
I found the storage rule for authenicated users etc but I don't use firebase authentication. Instead I authenticate users in the API that is hosted in google cloud run.
I think it is in this direction but please correct me if I am wrong.
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read: if true;
allow write: if request comes from my API with the Web API key;
}
}
}
sources:
https://firebase.google.com/docs/storage/security/rules-conditions
https://firebase.google.com/docs/storage/gcp-integration
There is no way to check what API key is used in the call to Cloud Storage.
But access from Cloud Run usually happens through one of the GCP SDKs/APIs and those access the project with administrative privileges and bypass your security rules altogether.
So you might as well deny all write access from untrusted clients with:
allow write: if false;

React-native-firebase and firebase configuration problem with firestore access

So I have my react-native project setup for firebase. I was mostly using analytics and crashlytics, and the firebase configuration files for both the ios and android deployments are correctly configured (the plist and json files), as I am able to use those services.
Now I want to also use the firestore. I was under the impression that the same configuration files with the firebase access info would be enough. But it doesn't seem to be the case. And I don't understand why.
My firebase access rule is simple enough:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /receipts/{receipt} {
allow read, write: if request.auth != null;
}
}
}
The error I'm getting is:
[Error: [firestore/permission-denied] The caller does not have permission to execute the specified operation.]
which goes away if I remove the if condition in the rule.
So I don't think the problem is there. I was wondering if for some reason firestore requires the web type configuration in my app, in the firebase.js file. But at this point I am doing trial and error development here...
Any insight would be much appreciated.

Do firebase storage rules override cloud storage permissions?

I have the following rules in my bucket:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read;
}
}
}
This says to me that public can read - but they can't. Checking on the google cloud storage UI, there is no 'public url'.
So a couple of questions:
Does firebase give a different URL for accessing the file which will issue permissions based on the above rule configuration?
There is a firebase-adminsdk service account in GCS bucket permissions - is that what firebase uses to access the bucket?
Which credentials overwrite each other?
​
Cloud Storage access permissions and Firebase's Storage rules are unrelated.
Firebase's Storage rules apply to users who access the data in the bucket through a Firebase SDK. In addition Firebase can generate a so-called download URL, which gives everyone who has that URL read-only access to that file.
Cloud Storage access permissions apply to users accessing the data in the bucket through a Cloud API. The Cloud Storage SDKs and APIs can also generate so-called signed URLs, which serve a similar role to the download URLs mentioned above.
Firebase security rules only affect direct access from web and mobile client apps when using the Firebase SDK, especially when the user is authenticated with Firebase Auth (as the user's account token is made available during the evaluation of rules).
Rule do not affect the way service accounts work, or other forms of public access that depend on Cloud Storage ACLs. Those are determined by their own permission systems. Those other systems don't also don't affect Firebase client access at all.

Trying to make app secure with API key, but it isn't being used

I've created a web application that displays data from my cloud firestore. I'm about to release it to the public, but I don't want just anyone to be able to read/write to my database.
I have currently restricted my API key to only allow requests from my website's url, but it doesn't seem to be doing anything. I've even deleted it from the app entirely and it is still able to access the database.
Is there a rule I need to set up in my firestore to make it require an API key? I've googled plenty of things, but all I can find are articles on why it's ok to have your key be available to the public.
It's not possible to restrict access to Firestore based on some plaintext API key or web site domain. If you're publishing an app that provides direct access to Cloud Firestore (or Cloud Storage, or Realtime Database), the only way to secure it is with a combination of Firebase Authentication and security rules. The security rules allow you to express who can read and write which collections and document.
If you aren't using Firebase Authentication, and your default security rules allow universal read/write access, then anyone with an internet connection will be able to read and write every document.
A slight variation on Doug's excellent answer is to allow all users to write to specific documents that pre-exist and that have impossible to guess names. These document names then essentially become your own API keys, that you share (out of band) with the users of your app.
The security rules for this can be as simple as:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow create: if false;
allow update: if exists(resource['__name__']);
allow get: if true;
allow list: if false;
}
}
}
So: anyone can get/update any existing document that they know the name of, but they can't create a document, nor get a list of all documents.
This prevents the need for using Firebase Authentication. On the other hand it means you can't lock down access on a per user basis. Any user that somehow gets access to the document name, can now read/write it at will.

how to pass firestore auth token using flutter cloud_firestore package

I am using firebase auth REST api to do authentication; this part works fine as I can log in/sign up users and I can get a uid and auth token back.
When trying to write to cloud firestore, if I set my Cloud Firestore database rule to (which is one of the most basic auth rules):
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
But how to pass in the uid to the a cloud firestore request using cloud_firestore package e.g. I want to write to a collection:
Firestore.instance.collection('myCollection').document() .setData(myData);
Just in case this helps someone else, I was told that I shouldn't mix firebase auth REST api with firestore non-REST api.
If I want to use cloud_firestore package, I shall use firebase_auth package too so that firebase_auth will take case of the underlying authentication without requiring cloud_firestore to pass any auth token explicitly.
In the meantime, firestore does have a REST api too; so if someone really wants to use firebase auth REST api, then firestore REST api should also be used so that an auth token can be passed explicitly.

Resources