I'm following this guide to setup firebase emulators to test my realtime database security rules: https://firebase.google.com/docs/emulator-suite/connect_rtdb#clear_your_database_between_tests
At "Clear your database between tests", it suggests doing:
firebase.database().ref().set(null);
However, my security rules prevent my app from doing so.
Here's my code:
import * as firebase from '@firebase/testing';
import fs from 'fs';
const app = firebase.initializeTestApp({
databaseName: 'myDb',
auth: {
uid: 'myuid',
},
});
describe('test', () => {
beforeEach(async () => {
await firebase.loadDatabaseRules({
databaseName: 'mydb',
rules: fs.readFileSync('database.rules.json', 'utf8'),
});
await app.database().ref().set(null) // This line throws a permission denied error
});
afterAll(async () => {
await Promise.all(firebase.apps().map((app) => app.delete()));
});
it('test', async (done) => {
// ... //
});
}
How can I reset my database between my tests?
Found a solution here
I need to use
firebase.initializeAdminApp({ databaseName: "myDb" });
to create an app that is authenticated as an admin. I can then reset the database between each test:
const app = firebase.initializeTestApp({
databaseName: 'myDb',
auth: {
uid: 'myuid',
},
});
const adminApp = firebase.initializeAdminApp({ databaseName: "myDb" });
let backup;
beforeEach(async () => {
await firebase.loadDatabaseRules({
databaseName: 'myDb',
rules: fs.readFileSync('database.rules.json', 'utf8'),
});
await adminApp
.database()
.ref('/')
.once('value')
.then((v) => {
backup = v.val();
})
});
afterEach(async ()=>{
await adminApp.database().ref('/').set(backup);
})