Функции Firebase вызываются дважды при работе в Google App Engine

Я использую firebase в гибкой среде Google App Engine. У меня есть добавленный дочерний слушатель, настроенный на узле, и он вызывается дважды каждый раз, когда я добавляю одного ребенка. Это происходит только тогда, когда я запускаю этот код в Google App Engine. Если я запускаю его локально, он работает должным образом. Вот код

// [START app]
'use strict';

var express = require('express');
var bodyParser = require('body-parser');
var request = require('request');
var firebase = require('firebase-admin');

var app = express();

firebase.initializeApp({
    credential: firebase.credential.applicationDefault(),
    databaseURL: "https://myurl.firebaseio.com/"
});

var db = firebase.database();
var globalNotifications = db.ref("/globalNotifications");

var API_KEY = "myKey"; // Your Firebase Cloud Server API key
var now = new Date();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

globalNotifications.orderByChild('processed').equalTo(0).on("child_added", function(snapshot) {

    var key = snapshot.key;
    var incomingNotification = snapshot.val();
    var userID = incomingNotification.userID;
    var notifyID = incomingNotification.notifyID;

    request({
        url: 'https://fcm.googleapis.com/fcm/send',
        method: 'POST',
        headers: {
            'Content-Type' :'application/json',
            'Authorization': 'key='+API_KEY
        },
        body: JSON.stringify({
            "to" : incomingNotification.notificationID,
            "priority" : "high",
            "notification" : {
                "body" : "someone is following you",
                "title" : "You have a new follower"
            }
        })
    }, function(error, response, body) {
        if (error) { console.error(error); }
        else if (response.statusCode >= 400) {
            console.error('HTTP Error: '+response.statusCode+' - '+response.statusMessage);
        }
        else {
            console.log(response.statusCode);
            console.log(body);
            globalNotifications.child(key).update({"processed": 1, "response": body});
        }
    });

});

// Start the server
var server = app.listen(process.env.PORT || '8080', function () {
    console.log('App listening on port %s', server.address().port);
    console.log('Press Ctrl+C to quit.');
});
// [END app]

Спасибо за любую помощь заранее.


person WikipediaBrown    schedule 05.12.2016    source источник


Ответы (1)


После некоторого тестирования я понял это. Эта проблема вызвана запуском Firebase-Admin в Google App Engine. По сути, каждая базовая виртуальная машина, на которой находится ваш AppEngine, запускает собственный экземпляр Firebase-Admin. AppEngine по умолчанию поддерживает как минимум две виртуальные машины для каждой службы. Таким образом, при тестировании (при минимальной нагрузке) функции firebase вызываются один раз каждым из двух экземпляров виртуальной машины.

Судя по всему, документации по этой проблеме нет, но есть библиотека от Google / Firebase, которая решает эту проблему. Это называется Firebase-Queue, и его можно найти на NPM. Я решил свою проблему с помощью этого кода:

// [START notificationsservice app]
'use strict';

var express = require('express');
var bodyParser = require('body-parser');
var request = require('request');
var rp = require('request-promise');
var admin = require('firebase-admin');
var Queue = require('firebase-queue');

var app = express();

admin.initializeApp({
    credential: admin.credential.cert("serviceAccountCredentials.json"),
    databaseURL: "https://<YOUR PROJECT ID HERE>.firebaseio.com/"
});

var db = admin.database();
var notifications = db.ref('/notifications');

var API_KEY = "<YOUR API KEY HERE>"

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

var queue = new Queue(notifications, function(data, progress, resolve, reject) {

    var incomingNotification = data;
    var userID = incomingNotification.userID;
    var username = incomingNotification.username;

    rp({
        url: 'https://fcm.googleapis.com/fcm/send',
        method: 'POST',
        headers: {
            'Content-Type' :'application/json',
            'Authorization': 'key='+API_KEY
        },
        body: JSON.stringify({
            "to" : "/topics/follower-"+userID,
            "priority": "high",
            "notification" : {
                "body" : username+" you have a notification",
            },
            "data" : {
                "type" : "follower"
            }
        })
    }).then(function(body) {
        progress(100);
        console.log("Notification sent."+body);
        resolve();
    }).catch(function(error) {
        progress(21);
        console.log(error);
        reject(); 
    });

  setTimeout(function() {
    resolve();
  }, 1000);
});

// Start the server
var server = app.listen(process.env.PORT || '8080', function () {
    console.log('App listening on port %s', server.address().port);
    console.log('Press Ctrl+C to quit.');
});
// [END app]
person WikipediaBrown    schedule 05.12.2016
comment
Спасибо, что нашли это и оказались более надежными, чем api движка приложений Google! - person importnumpyasnp; 08.02.2017