【问题标题】:Firebase functions being called twice while running on Google App Engine在 Google App Engine 上运行时 Firebase 函数被调用两次
【发布时间】:2016-12-05 19:10:09
【问题描述】:

我在 Google App Engine 柔性环境中运行 firebase。我在一个节点上设置了一个子添加侦听器,每次添加一个子时它都会被调用两次。这只发生在我在 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]

提前感谢您的帮助。

【问题讨论】:

    标签: node.js google-app-engine firebase-admin


    【解决方案1】:

    经过一段时间的测试,我想通了。此问题是由在 Google App Engine 上运行 Firebase-Admin 引起的。本质上,您的 AppEngine 所在的每个底层虚拟机都在运行自己的 Firebase-Admin 实例。默认情况下,AppEngine 为每个服务至少维护两个 VM。因此,在测试中(在最小负载下),两个 VM 实例中的每一个都会调用一次 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]
    

    【讨论】:

    • 感谢您发现这个并且比谷歌应用引擎 api 更可靠!
    猜你喜欢
    • 2011-04-11
    • 2016-10-19
    • 1970-01-01
    • 2019-03-02
    • 2013-03-31
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 2014-12-27
    相关资源
    最近更新 更多