2016-12-05 11 views
1

Google App Engine Flexible 환경에서 firebase를 실행 중입니다. 노드에 리스너를 추가 한 자식을 추가하고 자식을 한 명 추가 할 때마다 두 번 호출됩니다. 이는 Google App Engine에서이 코드를 실행하는 경우에만 발생합니다. 로컬로 실행하면 예상대로 작동합니다. 코드는 다음과 같습니다Google App Engine에서 실행되는 동안 Firebase 기능이 두 번 호출됩니다.

// [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] 

사전에 도움을 주셔서 감사합니다.

답변

3

잠시 동안 테스트 한 후에 나는 그것을 알아 냈습니다. 이 문제는 Google App Engine에서 Firebase-Admin을 실행하면 발생합니다. 기본적으로 AppEngine에있는 모든 기본 VM은 자체 Firebase-Admin 인스턴스를 실행합니다. AppEngine은 기본적으로 모든 서비스에 대해 최소 2 개의 VM을 유지 관리합니다. 그래서 (최소한의 부하 하에서) 테스트 할 때, firebase 함수는 두 개의 VM 인스턴스 각각에 의해 한 번 호출됩니다.

분명히이 문제에 대한 문서는 없지만이 문제를 해결하는 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] 
+1

Google 애플리케이션 엔진 API보다 더 신뢰할 수있는 기능을 제공 해주셔서 감사합니다. –