firebase / firebase/firebase-tools
RTDB emulator doesn't work properly with databaseAuthVariableOverride
- Dominant language
- TypeScript
- Stars
- 4.5k
- Forks
- 1.3k
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 84
Description
### [REQUIRED] Environment info
**firebase-tools:** 8.7.0
**Platform:** macOS
**node:** v10.22.0
**firebase-admin:** 9.1.0
**firebase-database-emulator:** v4.5.0
### [REQUIRED] Test case
Add some rules like the following:
```json
{
"rules": {
"$userId": {
"publicAccess": {
".validate": "newData.isBoolean()"
},
"data": {
".read": "$userId === auth.uid || (auth.token.auth_time >= ((now / 1000) - 60 * 60) && auth.token.customClaimAccess === $userId) || data.parent().child('publicAccess').val() === true"
}
}
}
}
```
### [REQUIRED] Steps to reproduce
```js
const admin = require('firebase-admin')
const adminApp = admin.initializeApp({
databaseURL: 'https://blah.firebaseio.com',
})
const noAuthApp = admin.initializeApp({
databaseURL: 'https://blah.firebaseio.com',
databaseAuthVariableOverride: null,
}, 'no-auth')
const userAuthApp = admin.initializeApp({
databaseURL: 'https://blah.firebaseio.com',
databaseAuthVariableOverride: {
uid: 'USER_ID_1',
},
}, 'user-auth')
const customClaimsAuthApp = admin.initializeApp({
databaseURL: 'https://blah.firebaseio.com',
databaseAuthVariableOverride: {
uid: 'USER_ABC',
token: {
customClaimAccess: 'USER_ID_2',
auth_time: (Date.now() / 1000)
},
},
}, 'custom-claims-auth')
const assert = require('assert').strict
async function test() {
await adminApp.database().ref().set({
USER_ID_1: {
data: {
blah: "hello1",
},
},
USER_ID_2: {
data: {
blah: "hello2",
},
},
USER_ID_3: {
publicAccess: true,
data: {
blah: "hello3",
},
}
})
await assert.rejects(noAuthApp.database().ref('USER_ID_1/data').once('value'), /permission_denied/i, 'Should deny access with noAuthApp as not accessing public data')
await assert.doesNotReject(userAuthApp.database().ref('USER_ID_1/data').once('value'), 'Should allow access with userAuthApp as accessing own data')
await assert.doesNotReject(customClaimsAuthApp.database().ref('USER_ID_2/data').once('value'), 'Should allow access with customClaimsAuthApp as accessing data specified in claims')
await assert.doesNotReject(noAuthApp.database().ref('USER_ID_3/data').once('value'), 'Should allow access with noAuthApp as accessing public data')
}
test().catch(error => {
console.error(error)
}).finally(() => Promise.all(admin.apps.map(a => a.delete())))
```
1. Run emulator `firebase --project blah emulators:start --only database` (can't use `emulators:exec` as need to keep it running to view the rule evaluations).
2. Run the above script against the emulator `FIREBASE_DATABASE_EMULATOR_HOST=localhost:9000 node script.js`.
3. View the evaluated DB rules: `http://localhost:9000/.inspect/coverage?ns=blah`
### [REQUIRED] Expected behavior
I'd expect the tests to pass and the `auth_time` rule to be evaluated 3 times - returning `true` once and `false` twice.
### [REQUIRED] Actual behavior
Rules are not always evaluated - seems to bail out...



To simplify the case when running:
```js
await assert.rejects(noAuthApp.database().ref('USER_ID_1/data').once('value'), /permission_denied/i, 'Should deny access with noAuthApp as not accessing public data')
```
I'd expect this rule to be evaluated (as there's no `auth.uid`):
`(auth.token.auth_time >= ((now / 1000) - 60 * 60) && auth.token.customClaimAccess === $userId) || data.parent().child('publicAccess').val() === true`

The whole rule seems not to be evaluated, despite the first rule being evaluated...!


Contributor guide
Research direction
Start the database emulator with `firebase --project blah emulators:start --only database`, then run the supplied Node.js reproduction with `FIREBASE_DATABASE_EMULATOR_HOST=localhost:9000`. Inspect the evaluated rules at `/.inspect/coverage?ns=blah`; done means all four assertions pass and the `auth_time` rule is evaluated three times, returning true once and false twice.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100