firebase-tools
firebase-tools copied to clipboard
Rules using resource.data run twice in Firestore emulator
Rules that use resource.data appear to be evaluated twice in the Firestore emulator. The first time always fails with an error, but the second one succeeds and allows/denies access as expected. This feels similar to #4325, but doesn't involve the use of onSnapshot (although I observed the same issue when using onSnapshot instead of getDoc).
Everything appears correct from the client side - the code doesn't appear to run twice, nor are any errors returned from the request. My rules using resource.data appear to work correctly when deployed to Firebase and don't show any errors in the Firebase console.
[REQUIRED] Environment info
firebase-tools: 12.4.6
Platform: Windows 11
[REQUIRED] Test case
Rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /projects/{projectId} {
allow read: if (request.auth != null) && (request.auth.uid != null) && (resource.data.owner == request.auth.uid);
}
}
}
Firestore data at /projects/doc_id_here (replacing doc_id_here with the ID of the doc and uuid_here with the UUID of the currently authenticated user):
{ owner: "uuid_here" }
Screenshot from Firestore emulator:
[REQUIRED] Steps to reproduce
Set up a project with the rules and data listed above, then make a request to it from the JS client SDK. For example:
import {doc, getDoc, getFirestore, connectFirestoreEmulator, Firestore} from 'firebase/firestore';
const firebaseApp = { /* Firebase app config here */ }
const firestore = getFirestore(firebaseApp);
connectFirestoreEmulator(firestore, location.hostname, 8080);
export function getProject(projectId) {
getDoc(doc(firestore, `projects/${projectId}`))
}
[REQUIRED] Expected behavior
The Firestore emulator shows one entry with the result of the request on the Requests tab.
[REQUIRED] Actual behavior
The Firestore emulator shows two entries for each request; the first one failing with an unknown error and the second one successfully evaluating the rules.
Click on the request to view details. There's an error icon at the top of the table and a green checkmark on the line containing the related rule, and the resource section under "Detailed information" in the right column reads (Error: unknown) (undefined):
Same here.
Did you find any workaround by any chance? @acmertz ?
I'm having this, too, and I suspect it causes the data never to resolve or throw an error; it just hangs forever. Did you experience that, maybe, or is it another emulator bug?
I'm seeing a similar issue on Mac. When I look into the logs on my IDE running the Firebase client it looks like only a single write is being performed but then I see this logged in the emulator Firestore requests.
Removing request.auth.uid == request.resource.data.userId from the firestore rules seems to fix the emulator logs.
Same here.
For my app, I use role-based security and I check user's capabilities via Firestore collection. If this case also appears in production, I wonder if my document reads will peak?
Sample Role Document
{
userId_12345: {
...
capabilities: [
"products.list",
"products.get"
...
],
...
}
}
Security Rule Function I wrote a function in security rules to get document and check capability for related action.
function checkCapabilities(request, capabilities) {
// Gets user's role from collection
let role = debug(
get(/databases/$(database)/documents/Claims/$(request.auth.uid)).data
);
return // boolean if capabilities match with required action capability or not.
}
** Sample Query**
This query fires double security rule check.
debug() function logs checkCapabilities, it logs twice too.
....
const querySnapshot = await getDocs(
query(
collection(
getFirestore(),
"Products"
),
where(
"companyId", "==", selectedCompanyId
)
)
.withConverter(productsConverter)
);
...
Emulator's Firestore Requests
Did you find any workaround by any chance?
@DavidWeiss2 I haven't found a proper workaround, unfortunately - in the meantime I've resorted to using a separate set of rules in my dev environment based on custom claims to cut down on the noise during development. This is less than ideal because it means I also have to test against my production ruleset before deploying. My application is fairly small so it isn't too difficult for me to run a smoke test of all critical features before deploying, but as it continues to grow, a proper fix or guidance from Firebase would definitely be appreciated.
This is also happening to me. For every successful rule evaluation there is a preceding one that always errors out.
Here a single request has been made:
Any idea if this issue exists only in emulator?
Yes, it is emulator only.
On Sun, Feb 18, 2024, 13:43 Piogar @.***> wrote:
Any idea if this issue exists only in emulator?
— Reply to this email directly, view it on GitHub https://github.com/firebase/firebase-tools/issues/6252#issuecomment-1951217354, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADBVIS57VR3IXW7QJSAIZ73YUHSPNAVCNFSM6AAAAAA3O2T6V2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNJRGIYTOMZVGQ . You are receiving this because you were mentioned.Message ID: @.***>
After upgrade firebase to version 13.4.0 still have this issue, Anyone got any idea to fix this now?
Experiencing same issue