firebase-functions: Permission denied on set value
I am simply doing this:
admin.database().ref(
/chat/last_message/${currentUserId}).set(currentTimestamp);
however I get:
FIREBASE WARNING: set at /chat/last_message/46wyOyreyYSocywqEt1g3943OAH2 failed: permission_denied
even though my database rule is only:
"chat": {
"last_message": {
"$uid": {
".write": true
}
},
}
Strange thing is I do the exact thing on my other firebase account, and it worked perfectly fine.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 21 (1 by maintainers)
Hey @azraelx23, I’m starting to get lost in all the different directions this is heading. Let me give you some general tips about how things are supposed to work and then maybe you can help put together a clear repro of the issue for me.
The
event.data
available as part of a Database Cloud Function is an instance ofDeltaSnapshot
. ThatDeltaSnapshot
has both aref
property and anadminRef
property. Theref
property has the same access to the Realtime Database as the client that triggered the Cloud Function. So, if an unauthenticated client triggered the Cloud Function, thenref
would likewise be unauthenticated. If instead an authenticated client triggered the Cloud Function, thenref
would likewise be authenticated as that client. TheadminRef
property has full read and write access to the Realtime Database and should (in theory) never see apermission_denied
error.In your initial post, you are using
admin.database().ref()
, but instead should probably be usingevent.data.adminRef
which is already authenticated for you. In your last post, you are usingevent.data.ref
which may just be failing because your Security Rules are indeed blocking the write.In order for me to help you, I’ll need to see an mcve of your problem. This would include the full contents of you
index.js
and the Security Rules you are using for the relevant nodes. Ideally, you’d be able to get rid of any extraneous code that isn’t part of the repro.Hope that helps.
Thanks @jwngr and firebase team! Great team effort!
Mystery solved! After a bunch of back and forth, we finally tracked down the underlying problem. Cloud Functions use your Firebase project’s App Engine default service account to authenticate
adminRef
. This service account is created automatically when your project is created and by default has an IAM permission of Editor. You can see what permission it has by looking here. In this case, the App Engine default service account has somehow gotten set to an IAM role of Viewer, which only granted it read access to the Realtime Database, not write access. The fix was simply to make it an Editor once again.Thanks to @azraelx23 for helping to debug this and being patient while we tracked it down!
@ahaverty sorry please ignore the very first post and check my latest sample code, it is a database trigger and it has transaction right on this line