Я разрабатываю веб-приложение NodeJS для получения обновлений в реальном времени из базы данных Firestore через Admin SDK.
Это код инициализации объекта 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;
Затем я использую этот объект firestore в сообщении websocket для отправки обновлений в реальном времени в браузер.Идея состоит в том, чтобы использовать сервер в качестве прокси между браузером и 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, оно работает, но я заметил огромную утечку памяти на сервере, мне нужна помощь