3

I create a project that uses React + Firebase + Lambda Functions.

I have Firebase code on the front end and I needed a bit of back-end to handle some events. (Prevent users from modifying data in Firebase but allow this data to be updated by the application)

As I use Netlify to deploy my app, I have access to Amazon Lambda Functions with netlify-lambda. (https://www.netlify.com/docs/functions/)

Usually everything just works (mailchimp API, snipcart API etc ...)

But I can not get Firebase working.

I created a service account with the rights to write and read.

Here the code of my lambda function: (Just a test to try to see the users section of the database.)

import firebaseAdmin from 'firebase-admin'
const serviceAccount = require('../utils/FirebaseServiceAccountKey.json')

export function handler (event, context, callback) {
  firebaseAdmin.initializeApp({
    credential: firebaseAdmin.credential.cert(serviceAccount),
    databaseURL: 'https://sample-3615.firebaseio.com'
  })

  const db = firebaseAdmin.database()
  const ref = db.ref('/users')
  let users = {}

  ref.once('value', function (snapshot) {
    console.log(snapshot.val())
    users = snapshot.val()
  })

  callback(null, {
    statusCode: 200,
    body: JSON.stringify({ users })
  })
}

It returns me : TypeError: rtdb.initStandalone is not a function.

I also have many Warning like this: Module not found: Error: Can not resolve 'memcpy' and for other packages too.

My call to the function in a Component:

handleClick = (e) => {
    e.preventDefault()

    this.setState({loading: true})
    fetch('/.netlify/functions/score')
      .then(res => res.json())
      .then(json => console.log(json.users))
      .then(() => this.setState({loading: false}))
  }

I'm not sure where the problem comes from. Webpack?

2
  • Have you see this answer? Commented Jul 25, 2018 at 16:02
  • OK thanks! I tried this solution. I modified the webpack config as indicated in the post but unfortunately it does not work with Gatsby. Commented Jul 25, 2018 at 22:07

2 Answers 2

3

I have not been able to run the SDK with AWS Lambda from Netlify.

To use Firebase from Netlify Lambda Functions I am going through the REST API with admin privileges.

https://firebase.google.com/docs/reference/rest/database/

It works perfectly like that.

import { google } from 'googleapis'
import fetch from 'node-fetch'
const serviceAccount = require('../utils/FirebaseServiceAccountKey.json')

const scopes = [
  'https://www.googleapis.com/auth/userinfo.email',
  'https://www.googleapis.com/auth/firebase.database'
]

// Authenticate a JWT client with the service account.
const jwtClient = new google.auth.JWT(
  serviceAccount.client_email,
  null,
  serviceAccount.private_key,
  scopes
)

export function handler (event, context, callback) {
  const res = JSON.parse(event.body)
  // Use the JWT client to generate an access token.
  jwtClient.authorize(async function (error, tokens) {
    if (error) {
      console.log('Error making request to generate access token:', error)
    } else if (tokens.access_token === null) {
      console.log('Provided service account does not have permission to generate access tokens')
    } else {
      const accessToken = tokens.access_token
      const score = await fetch(`https://example-3615.firebaseio.com/scores/${res.uid}/score.json`)
        .then(data => data.json())
        .then(score => score + res.score)

      fetch(`https://example-3615.firebaseio.com/scores/${res.uid}.json?access_token=${accessToken}`, {
        body: JSON.stringify({ score, displayName: res.user.displayName, photoURL: res.user.photoURL }),
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        method: 'PATCH'
      })
        .then(() => {
          callback(null, {
            statusCode: 200,
            body: 'Score +1'
          })
        })
    }
  })
}
Sign up to request clarification or add additional context in comments.

Comments

0

the problem was in "webpack.server.js" configuration file. netlify-lambda used to bundle the server-side code (function code) and for some reasons, it bundles it incorrectly. so i added new file to the project root "webpack.server.js":

//webpack.config.js
const path = require('path');
const pkg = require('./package')
const GenerateJsonPlugin = require('generate-json-webpack-plugin')


const externals = [
    'firebase-admin'
]

const genPackage = () => ({
    name: 'functions',
    private: true,
    main: 'index.js',
    license: 'MIT',
    dependencies: externals.reduce(
    (acc, name) =>
        Object.assign({}, acc, {
        [name]:
            pkg.dependencies[name] ||
            pkg.devDependencies[name]
        }),
    {}
    )
})


module.exports = {
    target: 'node',
    resolve: {
        mainFields: ['module', 'main']
    },
    externals: externals.reduce(
        (acc, name) => Object.assign({}, acc, { [name]: true }),
        {}
    ),
    plugins: [new GenerateJsonPlugin('package.json', genPackage())]
}

this file config will create a new package.json file placed in lambda dist.

UPDATE check my post on Medium (Firebase Admin with Netlify lambda functions)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.