it-swarm.com.de

Amazon Lambda zu Firebase

Ich erhalte die Meldung, dass das Modul 'Firebase' nicht gefunden werden kann, wenn ich versuche, dies in Lambda auszuführen (Node.js 4.3).

var Firebase = require('firebase');

Das gleiche passiert, wenn ich versuche, ein gezipptes Paket hochzuladen, das node_modules/firebase enthält

Hat jemand eine funktionierende Implementierung von Lambda to Firebase?

16
user2676299

Gehen Sie folgendermaßen vor, um das Firebase-npm-Paket (Version 3.3.0) in AWS Lambda (Nodejs 4.3) sicher zu verwenden:

'use strict';

var firebase = require("firebase");

exports.handler = (event, context, callback) => {
    context.callbackWaitsForEmptyEventLoop = false;  //<---Important

    var config = {
        apiKey: "<<apikey>>",
        authDomain: "<<app_id>>.firebaseapp.com",
        databaseURL: "https://<<app_id>>.firebaseio.com",
        storageBucket: "<<app_id>>.appspot.com",
    };

    if(firebase.apps.length == 0) {   // <---Important!!! In lambda, it will cause double initialization.
        firebase.initializeApp(config);
    }

    ...
    <Your Logic here...>
    ...
};
22
Josiah Choi

Ich habe mein Problem durch die Verwendung von Firebase REST api gelöst

var https = require('https');

exports.handler = function(event, context, callback) {

    var body = JSON.stringify({
        foo: "bar"
    })

   var https = require('https');

var options = {
  Host: 'project-XXXXX.firebaseio.com',
  port: 443,
  path: '/.json',
  method: 'POST'
};

var req = https.request(options, function(res) {
  console.log(res.statusCode);
  res.on('data', function(d) {
    process.stdout.write(d);
  });
});
req.end(body);

req.on('error', function(e) {
  console.error(e);
});

    callback(null, "some success message");

}
9
user2676299

Dies ist spät, aber falls jemand anderes sucht:

Das Zippen Ihres Projektordners anstelle von contents des Projektordners kann dies verursachen. Der gezippte Ordner sollte im entpackten Ordner keinen Ordner mit den Lambda-Dateien enthalten, er sollte jedoch die Datei index.js und den Ordner node_modules auf der Root-Ebene haben.

Ein funktionierendes Beispiel für eine Lambda-Funktion ist (mit neuesten glänzenden Firebase-Elementen * sigh *):

var firebase = require('firebase');

// Your service account details
var credentials = {
  "type": "service_account",
  "project_id": "project-123451234512345123",
  "private_key_id": "my1private2key3id",
  "private_key": "-----BEGIN PRIVATE KEY-----InsertKeyHere-----END PRIVATE KEY-----\n",
  "client_email": "[email protected]",
  "client_id": "1111222223333344444",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/projectname%40project-123451234512345123.iam.gserviceaccount.com"
};

firebase.initializeApp({
  serviceAccount: credentials,
  databaseURL: "https://project-123451234512345123.firebaseio.com"
});

exports.handler = function (event, context, callback) {

  // I use some data passed in from AWS API Gateway:
  if (!event.firebaseUid) {
    callback('Missing param for id');
  }

  firebase.database().ref().child('users').child(firebaseUid).child('at').set(newTokens.access_token).then(function (data) {
    console.log('Firebase data: ', data);
    firebase.database().goOffline();
    callback(null, 'Firebase data: ', data);
  }).catch(function (error) {
    callback('Database set error ' + error);
  });
 };

Nun zur Einschränkung. Ich habe erfahren, dass dies dazu führt, dass die Lambda-Funktion auch nach dem Firebase-Callback abläuft, d. H. Die Set-Funktion scheint einen Listener zu erstellen, der die Lambda-Funktion trotz korrekter Daten geöffnet hält.

Update: Durch Aufrufen von firebase.database (). GoOffline () wird das Zeitlimitproblem der Lambda-Funktion behoben, das bei mir aufgetreten ist.

Es gelten die üblichen Sicherheitsvorkehrungen, dass die Sicherheit nicht überprüft oder angemessen ist, und die Möglichkeiten, Raum und Zeit damit zu stoppen.

9
richter

2017-03-22 edit: Google hat gerade angekündigt Firebase Cloud-Funktionen , was ein viel besserer Weg ist, dies zu tun. Cloud-Funktionen funktionieren wie Lambda und können durch Firebase-Ereignisse ausgelöst werden.


Hier ist meine Lösung mit der REST api (damit Sie nichts require irgendetwas brauchen):

var https = require('https');
var firebaseHost = "yourapp.firebaseio.com";
function fbGet(key){
  return new Promise((resolve, reject) => {
    var options = {
      hostname: firebaseHost,
      port: 443,
      path: key + ".json",
      method: 'GET'
    };
    var req = https.request(options, function (res) {
      res.setEncoding('utf8');
      var body = '';
      res.on('data', function(chunk) {
        body += chunk;
      });
      res.on('end', function() {
        resolve(JSON.parse(body))
      });
    });
    req.end();
    req.on('error', reject);
  });
}

function fbPut(key, value){
  return new Promise((resolve, reject) => {
    var options = {
      hostname: firebaseHost,
      port: 443,
      path: key + ".json",
      method: 'PUT'
    };

    var req = https.request(options, function (res) {
      console.log("request made")
      res.setEncoding('utf8');
      var body = '';
      res.on('data', function(chunk) {
        body += chunk;
      });
      res.on('end', function() {
        resolve(body)
      });
    });
    req.end(JSON.stringify(value));
    req.on('error', reject);
  });
}

Sie können es so verwenden:

fbPut("/foo/bar", "lol").then(res => {
  console.log("wrote data")
})

Und dann:

fbGet("/foo/bar").then(data => {
  console.log(data); // prints "lol"
}).catch(e => {
  console.log("error saving to firebase: ");
  console.log(e);
})
3
cgenco

Eine andere Alternative, wenn Sie ein knotenbasiertes Entwicklungs-Setup verwenden, ist die Verwendung des node-lambda-Pakets von here . Im Wesentlichen werden Wrapper zum Einrichten, Testen und Bereitstellen von Lambda bereitgestellt. node-lambda deploy verpackt alle installierten Module (z. B. mit npm i --save firebase) und stellt sicher, dass sie bei Lambda selbst verfügbar sind. Ich habe es für die Verwaltung externer Module sehr hilfreich gefunden.

2
dsl101

Für mich sollte Firebase-Admin den Trick tun. https://firebase.google.com/docs/admin/setup

Vielen Dank für Josiah Choi für den Vorschlag von context.callbackWaitsForEmptyEventLoop. Lambda muss also nicht jedes Mal die Basisdatenbank initialisieren. Mein erster Lauf war sehr langsam.

  var firebase = require('firebase-admin');
  module.exports.Test = (event, context, callback) => {

  context.callbackWaitsForEmptyEventLoop = false;  //<---Important

  if(firebase.apps.length == 0) {   // <---Important!!! In lambda, it will cause double initialization.
    firebase.initializeApp({
      credential: firebase.credential.cert("serviceAccount.json"),
      databaseURL: <YOUR FIREBASE URL>
    });

  }


 firebase.database().ref('conversation').once('value').then(function(snapshot) {
    console.log (snapshot.val()) ;
   var bodyReturn = {
     input: snapshot.val()
   } ;

   callback(null,bodyReturn);
   context.succeed() ;
});

};

Nachdem ich ein paar Dinge ausprobiert habe, scheint das für mich zu funktionieren (v 3.10.8):

for(var i=0;i<5;i++)
{

    var firebase = require('firebase');
    var config = {
        apiKey: "",
        authDomain: "",
        databaseURL: "",
        storageBucket: "",
        messagingSenderId: ""
      };
        if(firebase.apps)
        if(firebase.apps.length==0)
      firebase.initializeApp(config)

        firebase.database().ref().child("test").once('value').
          then(function(snapshot) {
            console.log(snapshot.val());

                                 });

  }
0
Nick