Firebase-tools: TypeError: handler is not a function

Created on 9 May 2018  路  6Comments  路  Source: firebase/firebase-tools

Version Info
firebase-tools: 3.18.4
firebase-admin 5.12.0
firebase-functions: 1.0.2

Platform Information
Windows

When I run the firebase serve command on an isomorphic React implementation, I get the following stack message every time I use a route, I'm using Express.js, to render the react views as seen on the functions-samples repo

TypeError: handler is not a function at cloudFunction (~\Project\node_modules\firebase-functions\lib\providers\https.js:37:41) at app.use (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\@google-cloud\functions-emulator\src\supervisor\worker.js:142:11) at Layer.handle [as handle_request] (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5) at trim_prefix (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:317:13) at ~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:284:7 at Function.process_params (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:335:12) at next (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:275:10) at app.use (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\@google-cloud\functions-emulator\src\supervisor\worker.js:114:7) at Layer.handle [as handle_request] (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5) at trim_prefix (~\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:317:13)

Already uninstalled the emulator and re-install it, also deleted the config file ~/.config/configstore/@google-cloud/functions-emulator

Most helpful comment

The problem occurred because I forgot to add the libraryTarget: "commonjs2" option on the webpack config file

const config = {
  entry: ['./src/index.js'],
  target: 'node',
  externals: [nodeExternals()],
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'ssr.bundle.js',
    libraryTarget: 'commonjs2'
  },
  module: {
    rules: [
      {
        test: /\.js/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            babelrc: true,
          }
        }
      }
    ]
  },
  ...
}

All 6 comments

Could you share your functions code?

import React from 'react'
import { renderToString } from 'react-dom/server'
import express from 'express'
import helmet from 'helmet'
import morgan from 'morgan'
import status from 'http-status'

import { default as Bundle } from 'Bundle'
import template from './template'

const ServerApp = React.createFactory(Bundle)

const renderApplication = (url, res, initialState) => {
  const html = ReactDOMServer.renderToString(ServerApp({ url: url, context: {}, initialState }))
  const templatedHTML = template({ body: html, initialState: JSON.stringify(initialState) })
  res.status(status.OK).send(templatedHTML)
}

const app = express()

app.use(helmet())
app.use(morgan('dev'))
app.get('/favicon.ico', (req, res) => {
  return res.send(204)
})
app.get('/', (req, res) => {
  return renderApplication(req.url, res)
})

export default app
const functions = require('firebase-functions');
const app = require('./dist/ssr.bundle').default;

exports.app = functions.https.onRequest(app);

I am actually transiling the code with webpack & babel

It seems like the error comes from this line:

exports.app = functions.https.onRequest(app);

It is complaining that app is not a function. Could you add a console log above that line to print out what app is and share what you see?

info: undefined

This is really revealing, I will get back to my transpiled code, and try to figure out how come the bundle is not returning what I expected.

Thank you so much for your help!

The problem occurred because I forgot to add the libraryTarget: "commonjs2" option on the webpack config file

const config = {
  entry: ['./src/index.js'],
  target: 'node',
  externals: [nodeExternals()],
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'ssr.bundle.js',
    libraryTarget: 'commonjs2'
  },
  module: {
    rules: [
      {
        test: /\.js/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            babelrc: true,
          }
        }
      }
    ]
  },
  ...
}

Glad you figured it out!

Was this page helpful?
0 / 5 - 0 ratings