web-dev-qa-db-fra.com

Amazon Lambda à Firebase

Je reçois le message 'Impossible de trouver le module' Firebase 'quand j'essaie de l'exécuter en Lambda (Node.js 4.3)

var Firebase = require('firebase');

La même chose se produit lorsque j'essaye de télécharger un paquet zippé qui inclut node_modules/firebase

Quelqu'un a-t-il une implémentation "d'écriture de lambda vers firebase" de travail?

16
user2676299

Pour utiliser le package firebase npm (version 3.3.0) en toute sécurité dans AWS Lambda (Nodejs 4.3), procédez comme suit:

'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

J'ai résolu mon problème en utilisant firebase REST api

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

C'est tard, mais si quelqu'un d'autre cherche:

Cela peut être causé par la compression du dossier de votre projet à la place des contenus du dossier de projet. Le dossier compressé, une fois extrait, ne doit pas contenir de dossier contenant les fichiers lambda, mais doit contenir le fichier index.js et le dossier node_modules au niveau de la racine.

Un exemple de travail d’une fonction lambda est (en utilisant la dernière substance brillante * 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);
  });
 };

Maintenant pour la mise en garde. J'ai constaté que la fonction lambda avait expiré même après le rappel de la base de feu, c.-à-d. la fonction set semble créer un écouteur qui maintient ouverte la fonction lambda malgré le retour des données correctes.

Mise à jour: L'appel de firebase.database (). GoOffline () corrige le problème de délai d'attente de la fonction Lambda que je rencontrais.

Les précautions habituelles concernant la non-vérification ou l’absence de sécurité et la possibilité d’arrêter l’espace et le temps en utilisant cette règle s’appliquent.

9
richter

2017-03-22 edit: Google vient d’annoncer les fonctions cloud de firebase , ce qui est une bien meilleure façon de procéder. Les fonctions cloud fonctionnent comme lambda et peuvent être déclenchées à partir d’événements firebase.


Voici ma solution en utilisant le REST api (donc vous n'avez pas besoin de require rien):

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);
  });
}

Vous pouvez l'utiliser comme ceci:

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

Et alors:

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

Une autre alternative si vous utilisez une configuration de développement basée sur un nœud consiste à utiliser le package node-lambda à partir de ici . Il fournit essentiellement des wrappers pour configurer, tester et déployer sur lambda. node-lambda deploy conditionnera tous les modules que vous avez installés (par exemple avec npm i --save firebase) et s'assurera qu'ils sont disponibles sur Lambda lui-même. Je l'ai trouvé très utile pour gérer des modules externes.

2
dsl101

Pour moi, firebase-admin devrait faire l'affaire. https://firebase.google.com/docs/admin/setup

Merci à Josiah Choi d’avoir suggéré context.callbackWaitsForEmptyEventLoop. Donc, lambda n'a pas besoin d'initialiserFirebase à chaque fois. Ma première course était vraiment lente.

  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() ;
});

};
1

Après avoir essayé plusieurs choses, cela semble fonctionner pour moi (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