【发布时间】:2021-08-22 10:24:56
【问题描述】:
我有一个 2014 年的网络应用程序,它仍在使用 firebase-token-generator 在后端生成自定义身份验证令牌,并在客户端生成 Firebase JS SDK 2.x。
这是一个开源项目,但没有人可以自己托管它,因为当创建一个新的 Firebase 项目时,不再生成已弃用的firebase-token-generator 库工作所需的令牌。
我决定将它迁移到 Firebase Admin SDK 和最新版本的 JS SDK。我认为它进展顺利,我没有收到任何错误,但看起来一些以前运行良好的规则,不再按预期工作。以下是数据库规则:
{
"rules": {
"rooms": {
"$roomid": {
// You can see people in the room only if you are in it as well
".read": "auth != null && data.child('users').hasChild(auth.uid)",
"users": {
"$uid": {
// You can modify only your own info
".write": "auth != null && $uid == auth.uid",
}
}
}
}
}
}
这是一个简化的客户端代码:
const firebaseConfig = {...};
firebase.initializeApp(firebaseConfig);
// Get custom auth token from the server
const response = await fetch('/auth');
const data = await response.json();
const auth = window.firebase.auth();
await auth.signInWithCustomToken(data.token);
const user = { uuid: data.id };
const roomName = 'firebase-test'
const database = window.firebase.database();
const connectionRef = database.ref('.info/connected');
const roomRef = database.ref(`rooms/${roomName}`);
const usersRef = roomRef.child('users');
const userRef = usersRef.child(data.id);
window.users = {};
connectionRef.on('value', (connectionSnapshot) => {
if (connectionSnapshot.val() === true) {
// Remove yourself from the room when disconnected
userRef.onDisconnect().remove();
// Add yourself to the room
userRef.set(user);
// Watch for added users
usersRef.on('child_added', (userAddedSnapshot) => {
const addedUser = userAddedSnapshot.val();
window.users[addedUser.uuid] = addedUser;
});
// Watch for removed users
usersRef.on('child_removed', (userRemovedSnapshot) => {
const removedUser = userRemovedSnapshot.val();
delete window.users[removedUser.uuid];
});
}
});
}
和服务器代码:
app.get('/auth', async (req, res, next) => {
const uid = uuidv4();
const token = await firebaseAdmin.auth().createCustomToken(uid);
res.json({ id: uid, token });
});
现在,我没有收到任何错误,但是例如当用户关闭或重新加载页面时,有时它们不再从数据库中删除。有时,用户不会收到有关添加的新用户的更新。我尝试使用 Firebase 模拟器对其进行调试,但我只能发现数据库规则中的 $uid == auth.uid 之类的检查有时会开始失败,即使它们在迁移之前运行良好。
我创建了 2 个演示来说明这个问题。这是使用旧 SDK 的版本的链接:https://codesandbox.io/s/firebase-issue-test-old-sdk-loukt,这是使用新 SDK 的版本的链接:https://codesandbox.io/s/firebase-issue-test-new-sdk-c9lwh。如果您在 2 个选项卡中打开后者,然后重新加载一个选项卡,然后重新加载另一个选项卡,然后再次重新加载第一个选项卡,依此类推,您会看到用户没有被删除。使用旧 SDK 的版本按预期工作。两个版本的客户端代码几乎完全相同。
有谁知道这段代码可能有什么问题以及如何确保从数据库中正确删除关闭页面的用户?
【问题讨论】:
标签: javascript firebase-realtime-database firebase-authentication firebase-security