0
votes

New content for describing more specifically

I'm trying to use express and firebase function for advanced routing.

But I've got this error when I trying to get my firebase cloud function

TypeError: Cannot read property 'apply' of undefined at /Users/fredriccliver/Projects/firebase-test/functions/node_modules/express/lib/router/index.js:635:15 at next (/Users/fredriccliver/Projects/firebase-test/functions/node_modules/express/lib/router/index.js:260:14) at Function.handle (/Users/fredriccliver/Projects/firebase-test/functions/node_modules/express/lib/router/index.js:174:3) at router (/Users/fredriccliver/Projects/firebase-test/functions/node_modules/express/lib/router/index.js:47:12) at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:593:20 at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:568:19 at Generator.next () at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:8:71 at new Promise () at __awaiter (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:4:12)

/functions/index.js

const functions = require("firebase-functions")
const admin = require("firebase-admin")
const cors = require("cors")
const express = require("express")
const apiRoute = require("./api")

// admin.initializeApp(functions.config().firebase)

const app = express()
app.use(cors)

app.use("/api", apiRoute)

exports.api = functions.https.onRequest(apiRoute)

/functions/api.js

const router = require("express").Router()

router.get("/data", (req, res) => {
  res.send(`this is data`)
})

module.exports = router

Could anyone give me a clue to solve this problem?


Previous content

I'm trying to convert my node(with express) project into Firebase compatible one.

I add my API endpoint in /functions/index.js

const apiRoute = require("./routes/api")
exports.api = functions.https.onRequest(apiRoute)

And in my api.js

router.get("/", (req, res) => {
  res.send("api is running on")
})

router.get("/sentences", (req, res) => {
  res.send("hi")
})

So, my expectation was when I call localhost:5000/api or localhost:5000/api/sentences, I could get a response, but it doesn't work.

For that, I tried .onCall to submit my cloud function rather than using .onRequest.

But only POST request was accepted when I call functions.httpsCallable("endpoint").

So, I tried to use onRequest and rewrites in hosting in firebase.json

"hosting": {
    "public": "public",
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
    "rewrites": [
      {
        "source": "/api/**",
        "function": "api"
      }
    ]
  },

But, I just got this error:

TypeError: Cannot read property 'apply' of undefined at /Users/fredriccliver/Projects/Speech/functions/node_modules/express/lib/router/index.js:635:15 at next

How should I take the way to call my functions from frontend javascript?

2
While you convert your app, did you move the Cloud Function to Firebase Cloud Function at the same time?Shawn Di Wu
@ShawnDiWu Yes, I'm gonna use all the feature of firebase from my express nodejs project. Did you mean I would intend to use both of hosting and functions at the same time? I'm based on firebase console. So I mean I will convert my express routing into firebase cloud functionsFredric Cliver

2 Answers

2
votes

Your routes should include the full path of the URI proxied from Firebase Hosting.

router.get("/api", (req, res) => {
  res.send("api is running on")
})

router.get("/api/sentences", (req, res) => {
  res.send("hi")
})

I believe you can also use use() to specify a common prefix for every route in the app.

0
votes

I resolved after check a youtube clip and trying some more.

summarised on my medium post. https://medium.com/@fredriccliver/how-to-use-an-express-router-within-the-cloud-function-developing-environment-cb64face4043

functions/index.js

const functions = require("firebase-functions")
const express = require("express")
const app = express()

// my routings
const apiRoute = require("./api")

// add routes to the express app.
app.use("/api", apiRoute)

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

functions/api.js

const router = require("express").Router()

router.get("/api/user/data", (req, res) => {
  res.send(`this is /api/user/data`)
})

router.get("/api/data", (req, res) => {
  res.send(`this is /api/data`)
})

router.get("/api/api", (req, res) => {
  res.send(`here is /api/api`)
})

router.get("/api", (req, res) => {
  res.send(`here is /api`)
})

router.get("/data", (req, res) => {
  res.send(`here is /data`)
})

router.get("/", (req, res) => {
  res.send(`here is /`)
})

module.exports = router

/firebase.json


{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [{
      "source": "/api/**",
      "function": "api"
    }]
  }
}

So, I could approach all endpoints