I have a cloud function that responds to firestore events.
I want this cloud function to manipulate files on the storage of the same project.
const file = admin.storage().bucket().file('dataPackages/logos/pizza.png');
console.log('file exists', file.exists());
The project has anonymous authentication enabled, and the rules for the storage are
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
// allow read, write: if request.auth!=null;
allow read, write: if true;
}
}
}
For some reason I get this error
ApiError: shakescratchpad#appspot.gserviceaccount.com does not have storage.objects.get access to shakescratchpad.appspot.com/dataPackages/logos/pizza.png
Related
My app receives a webhook from a 3rd party service, telling it that data is ready to be queried.
The webhook payload includes:
UserId
ObjectId of the object whose data is ready.
In order to query the data, I need to get an access token:
const { accessToken } = await db
.collection('users').doc(userId)
.collection('objects').doc(objectId)
.get();
// then I can:
fetchUpdatedData(objectId, accessToken)
However, I have rules in place to require that users' data may only be accessed by the user:
# `firestore.rules`
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Reject by default
match /{document=**} {
allow read, write: if false;
}
// Users can edit their own document
match /users/{userId} {
allow read, update, delete: if request.auth.uid == userId;
allow create: if request.auth.uid != null;
}
// Users can manage their subcollections
match /users/{userId}/{document=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
What's the typical way to do this?
It's not possible to use security rules to limit queries coming from backends like Cloud Functions that use any of the server SDKs. Server SDKs initialize with a service account, which always bypass security rules. You're going to have to duplicate the relevant checks from the rules in your backend code to check if the query should be done on behalf of the user.
I have some Firestore rules that look like this:
firestore.rules
service cloud.firestore {
match /databases/{database}/documents {
match /adac/{documentID} {
allow read;
allow write: if request.auth.token.admin == true;
}
}
}
Does the same work for storage rules?
storage.rules
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth.token.admin == true; // <---- CAN I DO THIS ?
}
}
}
I mean, will my Storage get the same request object that my Firestore does?
Yes, custom claims are available in security rules for both Firestore and Storage.
Please refer to the API documentation for both Firestore and Storage.
I recently changed the firestore rules to the following rules:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
}
This should only allow authenticated users to access firestore. I'm using react-native as the frontend framework and it signs the user in anonymously if the user isn't already logged in. So all the requests going to firestore are from an authenticated user(anonymous or logged-in). However, after I updated the rules, the app isn't fetching anything from firestore. Are there any changes that must be done in the frontend after updating firestore rules?
[UPDATE] react-native throws me this error: FirebaseError: [code=permission-denied]: Missing or insufficient permissions.
You've got an extra match statement in there that's messing things up. If you just want all your authenticated users to have full read, write access to your full Firestore database, you'd just use:
service cloud.firestore {
match /databases/{database}/documents {
allow read, write: if request.auth.uid != null;
}
}
In my django server I am sending fcm notifications using firebase-admin and also creating some documents via my server. Whenever I try to send the notification in my server it gives an error
"firebase_admin.messaging.ApiCallError: The caller does not have permission",
I think it is due to my firestore security rules. Here is my current security rule in firestore. Is there a way to check if my request is from the admin and is secure?
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if isSignedIn() && emailVerified();
}
match /user/{userId} {
allow read: if isSignedIn() && emailVerified();
allow write: if isSignedIn();
}
function isSignedIn() {
return request.auth != null;
}
function emailVerified() {
return request.auth.token.email_verified
}
function isOwner(userId) {
return request.auth.uid == userId;
}
}
}
The Firebase Admin SDKs run with administrative privileges, which means they bypass the server-side security rules for the database.
You error is coming from firebase_admin.messaging, which is a call to Firebase Cloud Messaging. That call is not affected by your Firestore security rules in any way.
From the error message, is is most likely that you're not passing the FCM server token into the call correctly.
I am trying to download images from Firebase storage but I am getting errors.
E/StorageUtil: error getting token java.util.concurrent.ExecutionException: com.google.android.gms.internal.zzanu: Please sign in before trying to get a token.
W/NetworkRequest: no auth token for request
However, I have my rules set up like this:
service firebase.storage {
match /b/<myappnameredacted>.appspot.com/o {
match /{allPaths=**} {
allow read, write;
}
}
}
Your rules are not like in the Firebase Storage Security Rules Documentation.
For make all your files public (for anyone), use :
// Anyone can read or write to the bucket, even non-users of your app.
// Because it is shared with Google App Engine, this will also make
// files uploaded via Google App Engine public.
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
For make all your files readable (for anyone), use :
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read;
}
}
}
You can also make only your image readable / writable, see the Firebase Storage Security Rules Documentation.