2017-08-21 2 views
1

Ich habe meine Firebase-Cloud-Funktion, in der ich meinen externen API-Endpunkt so nenne.Firebase Cloud-Funktionen inkonsistent mit Bulk-Updates

const functions = require('firebase-functions'); 
var admin = require("firebase-admin"); 
admin.initializeApp(functions.config().firebase); 
var request = require('request'); 
var moment = require('moment'); 
var rp = require('request-promise'); 

var db = admin.database(); 

exports.onCheckIn = functions.database.ref('/news/{newsId}/{entryId}') 
     .onCreate(event => { 
     console.log("Event Triggered"); 
     var eventSnapshot = event.data.val(); 
     request.post({ 
       url: 'http://MyCustomURL/endpoint/', 
       form: { 
       data: eventSnapshot.data 
      } 
      }, function(error, response, body){ 

       console.log(response); 

      }); 



     }) 

Ich benutze Blaze Plan und das funktioniert völlig in Ordnung. Aber das Problem ist, dass, wenn ich Massen-Daten erstellen (etwa 50 bis 100 Einträge) die HTTP-Anfrage an meine benutzerdefinierte URL nicht richtig funktioniert. Ein oder zwei HTTP-Anfrage werden übersprungen.

Ich habe meinen benutzerdefinierten Server debugged und festgestellt, dass es keine fehlenden Anfragen von Firebase erhalten. Aber ich habe auch die Cloud-Funktionsprotokolle überprüft und kann feststellen, dass jedes Ereignis korrekt ausgelöst wird.

Was könnte das Problem sein? Mache ich etwas falsch?

Antwort

5

Sie geben keinen Wert von Ihrer Funktion zurück. Das bedeutet, dass Cloud Functions davon ausgeht, dass die Funktion mit ihrer Arbeit ausgeführt wird, nachdem die letzte Anweisung ausgeführt wurde. Da Sie jedoch in der Funktion einen asynchronen HTTP-Aufruf durchführen, sind diese Aufrufe möglicherweise noch nicht abgeschlossen. Leider teilen Sie Cloud Functions nicht mit, dass Sie einen ausstehenden Anruf haben, sodass Ihre Funktion jederzeit nach Ihrer Rückkehr beendet werden kann.

Die Lösung besteht darin, eine Zusage zurückzugeben, die nach Abschluss der HTTP-Anforderung aufgelöst wird. Da Sie bereits request-promise einschließlich hierfür ist einfach:

exports.onCheckIn = functions.database.ref('/news/{newsId}/{entryId}') 
.onCreate(event => { 
    console.log("Event Triggered"); 
    var eventSnapshot = event.data.val(); 
    return rp.post({ 
     url: 'http://MyCustomURL/endpoint/', 
     form: { 
     data: eventSnapshot.data 
     } 
    }); 
}) 

Diese für Entwickler neue JavaScript ein weit verbreitetes Problem ist, oder mit JavaScript und Firebase und ist in bedeckt: