I have a Firebase cloud function that does this:
const admin = require('firebase-admin')
admin.initializeApp()
exports.setSessionState = functions.https.onCall(async (data, context) => {
const stateId = data.stateId
const details = data.details
const stateRef = admin.database().ref(`state/${stateId}`)
stateRef.transaction((state) => {
if (state) {
state.details = details
}
return state
})
})
The code works well in the actual application and the state is updated but I run into problems when running this in a test, where the state is always null. (In other words, the details are never set.) The test uses the Mocha framework and is run against a real Firebase project and I can't see how anything would differ here but the behaviour is consistently different when calling this cloud function from the client application and when calling it from the test suite:
const chai = require('chai')
const assert = chai.assert
const test = require('firebase-functions-test')({
databaseURL: '<redacted>',
storageBucket: '<redacted>',
projectId: '<redacted>',
}, '../service-account-credentials.json')
describe('CFsetSessionState', () => {
let wrapped
let cloudFunctions
let admin
before(() => {
cloudFunctions = require('../index')
admin = require('firebase-admin')
wrapped = test.wrap(cloudFunctions.CFsetSessionState)
})
it('Test setting state', async () => {
const stateId = 'abc'
const data = {
stateId: stateId,
details: {
name: 'New name'
}
}
const context = {
auth: {
uid: 123
}
}
const stateRef = admin.database().ref(`state/${stateId}`)
await stateRef.set({
name: 'Previous name',
active: true
})
await wrapped(data, context)
const snapshot = await stateRef.once('value')
const state = snapshot.val()
// Details do not exist here, why?
assert.equal(state.details.name, 'New name')
})
})
I leave the database state as is after the tests so I can see there is indeed data in the state object but the details have not been set. Experimenting a bit with setting and fetching data (using .once()) before and after the call to the cloud function can change the behaviour, making me think it might be some cache issue, but this experimenting does not give me any particular stable end state. I have no idea how the equivalent of a local cache works in cloud functions, it currently shows random behaviour.
What could cause this?