我正在开发一个 NodeJS Web 应用程序以通过 Admin SDK 从 Firestore DB 接收实时更新。
这是 Firestore 对象的初始化代码。它只执行一次,在部署应用程序时(在 AWS Elastic Beanstalk 上):
const admin = require('firebase-admin');
var serviceAccount = require('./../key.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
var db = admin.firestore();
FUNC.firestore = db;
然后我在 websocket 通信中使用这个 firestore 对象向浏览器发送实时更新。这个想法是使用服务器作为浏览器和 Firestore 之间的代理。
socket.on('open', function (client) {
var query = FUNC.firestore.collection("notifications").doc(client.user.id.toString()).collection("global");
query.onSnapshot(querySnapshot => {
querySnapshot.docChanges().forEach(change => {
client.send({ id: change.doc.id, body: change.doc.data(), type: change.type });
});
}, err => {
console.log(`Encountered error: ${err}`);
});
});
socket.on('close', function (client) {
var unsub = FUNC.firestore.collection("notifications").doc(client.user.id.toString()).collection("global").onSnapshot(() => {
});
unsub();
});
它在一段时间内运行良好,但几个小时后客户端停止接收onSnapshot()
更新,一段时间后服务器记录错误:Encountered error: Error: 10 ABORTED: The operation was aborted.
怎么了?我应该在每个连接上初始化 firestore 吗?是否存在一些生命周期错误?
谢谢
编辑(一个非常糟糕的解决方案)
我尝试为每个登录的用户创建一个 firebase-admin 应用程序实例,并以这种方式更改了我的代码
const admin = require('firebase-admin');
var serviceAccount = require('./../key.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
FUNC.getFirestore = function (user) {
try {
user.firebase = admin.app(user.id.toString());
return user.firebase.firestore();
} catch(e) {
//ignore
}
var app = admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
}, user.id.toString());
user.firebase = app;
return user.firebase.firestore();
}
FUNC.removeFirebase = function (user) {
if (user.firebase) {
user.firebase.delete();
}
}
然后是套接字侦听器:
self.on('open', function (client) {
var query = FUNC.getFirestore(client.user).collection("notifications").doc(client.user.id.toString()).collection("global");
query.onSnapshot(querySnapshot => {
querySnapshot.docChanges().reverse();
querySnapshot.docChanges().forEach(change => {
client.send({ id: change.doc.id, body: change.doc.data(), type: change.type });
});
}, err => {
console.log(`Encountered error: ${err}`);
});
});
self.on('close', function (client) {
var unsub = FUNC.getFirestore(client.user).collection("notifications").doc(client.user.id.toString()).collection("global").onSnapshot(() => {
});
unsub();
FUNC.removeFirebase(client.user);
});
因此,当客户端由于某种原因断开连接时,服务器删除了它的 firebase 应用程序,它可以工作,但我注意到服务器上有巨大的内存泄漏,我需要一些帮助