在我的第二代云功能中,我有以下代码:
export const roomEnter = functions.https.onCall(async (request: any) => {
// initial validation to verify user authentication and valid request data passes first
...
const roomRef = admin.database().ref(`rooms/${request.data.roomId}`);
const roomSnapshot = await roomRef.once("value");
const testDataExists = {
exists: roomSnapshot.exists(),
data: roomSnapshot.val()
};
functions.logger.log("[room enter] CHECK ROOM EXISTS:", JSON.stringify(testDataExists));
// In the logs, the data that exists DOES print to the console successfully
const transactionRef = admin.database().ref(`rooms/${request.data.roomId}`);
const transactionResult = await transactionRef.transaction((currentData) => {
functions.logger.log("[room enter] Transaction current data:", JSON.stringify(currentData));
// In the logs, `currentData` prints as `null`, why?
// As a result, the transaction never gets beyond this condition and fails i assume after it has exhausted all internal retries
if (currentData !== null) {
if (currentData.memberTotal) {
currentData.memberTotal += 1;
} else {
currentData.memberTotal = 1;
}
return currentData;
} else {
functions.logger.log("[room enter] Transaction needs to retry, room current data is null", {
roomId: request.data.roomId
});
return; // Returning undefined should cause Firebase to retry the transaction
}
});
if (transactionResult.committed) {
// never able to reach this point
} else {
functions.logger.log("[room enter] transaction to increment member total failed");
throw new functions.https.HttpsError("internal", "transaction to increment member total failed", {
customData: {
roomId: request.data.roomId
}
});
}
...
});
测试
read
我在做交易之前只是作为一个测试来确认数据的存在。
正如上面的代码注释中所指出的,尽管现有数据的引用路径已被确认存在,但事务仍会失败。
除了尽可能记录错误之外,我不知道如何解决这个问题。
我拥有的其他不使用事务的云功能可以毫无问题地读取和写入数据库。
除了日志之外,我唯一的额外信息是,客户端将错误报告给客户端,作为500内部服务器错误以及包含消息的错误响应
transaction to increment member total failed
。
关于我的数据库安全规则,作为一个测试,尽管这与我正确验证的管理员SDK无关,但我已经设置了
".write": true
对于
rooms
和
rooms/$roomId
以便将其排除为可能的原因。
那么,为什么
currentData
null
交易内部?
我还能做些什么来排除故障?