【问题标题】:Firebase Hosting + Cloud FunctionFirebase 托管 + 云功能
【发布时间】:2020-06-13 17:47:56
【问题描述】:

难以部署我的功能以及托管。

问题是,我已经让它们在单独的分支上独立工作,但是..当尝试集成托管和我的云功能时,我的云功能似乎没有部署。我的终端没有收到任何错误,当我在 Firebase 控制台中单击“功能”时,它是默认屏幕,好像没有部署任何功能。

这是我用于托管 + 功能部署的 firebase.json。 托管在这里有效,但功能未部署

{
  "hosting": {
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      },
      {
        "source": "/api/v1/**",
        "function": "webApi"
      }
    ]
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint"
    ],
    "source": "functions"
  }
}

这是我的 firebase.json,只有功能,没有托管

{
  "hosting": {
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "/api/v1/**",
        "function": "webApi"
      }
    ]
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint"
    ],
    "source": "functions"
  }
}

这是我的函数/index.js

const functions = require('firebase-functions')
const admin = require('firebase-admin')
const serviceAccount = require('./serviceAccount.json')

const express = require('express')
const bodyParser = require('body-parser')

const _ = require('lodash')
const { getObjectValues } = require('./helper-functions.js')
const json2csv = require('json2csv').parse

admin.initializeApp({
  ...,
})
const db = admin.firestore()

const app = express()
const main = express()

main.use('/api/v1', app)
main.use(bodyParser.json())
exports.webApi = functions.https.onRequest(main)

app.get('/test', (request, response) => {
  response.send('API TEST')
})

app.get('/surveys', (request, response) => {
  const surveyCollection = db.collection('/surveys')
  return (
    surveyCollection
      .get()
      // eslint-disable-next-line promise/always-return
      .then(querySnapshot => {
        let surveyList = []
        querySnapshot.forEach(doc => {
          const survey = doc.data()
          surveyList.push(survey)
        })
        response.send(surveyList)
      })
  )
})

app.get('/surveys/:survey', (request, response) => {
  const surveyId = request.params.survey
  const userAnswers = db.collection(`/surveys/${surveyId}/submissions`)
  return (
    userAnswers
      .get()
      // eslint-disable-next-line promise/always-return
      .then(querySnapshot => {
        let surveySubmissions = []
        querySnapshot.forEach(doc => {
          const userSubmission = doc.data()
          surveySubmissions.push({
            ..._.mapValues(userSubmission.answers, getObjectValues), // format answers
            ...userSubmission.anonUser,
          })
        })
        response.setHeader('Content-disposition', 'attachment; filename=cna.json')
        response.set('Content-Type', 'application/json')
        response.status(200).send(surveySubmissions)
      })
      .catch(error => {
        console.log(error)
      })
  )
})

托管+功能分支,我输入'firebase deploy'

terminal output:

    i  deploying functions, hosting
Running command: npm --prefix "$RESOURCE_DIR" run lint

> functions@ lint \surveyplus-cna\functions
> eslint .

+  functions: Finished running predeploy script.
i  functions: ensuring necessary APIs are enabled...
+  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (82.32 KB) for uploading
+  functions: functions folder uploaded successfully
i  hosting[surveyplus-effd5]: beginning deploy...
i  hosting[surveyplus-effd5]: found 30 files in build
+  hosting[surveyplus-effd5]: file upload complete
i  functions: updating Node.js 8 function webApi(us-central1)...
+  functions[webApi(us-central1)]: Successful update operation.
i  hosting[surveyplus-effd5]: finalizing version...
+  hosting[surveyplus-effd5]: version finalized
i  hosting[surveyplus-effd5]: releasing new version...
+  hosting[surveyplus-effd5]: release complete

+  Deploy complete!

仅云端功能分支 firebase deploy输出

=== Deploying to '...'...

i  deploying functions, hosting
Running command: npm --prefix "$RESOURCE_DIR" run lint

> functions@ lint \surveyplus-cna\functions
> eslint .

+  functions: Finished running predeploy script.
i  functions: ensuring necessary APIs are enabled...
+  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (82.33 KB) for uploading
+  functions: functions folder uploaded successfully
i  hosting[surveyplus-effd5]: beginning deploy...
i  hosting[surveyplus-effd5]: found 30 files in build
+  hosting[surveyplus-effd5]: file upload complete
i  functions: updating Node.js 8 function webApi(us-central1)...
+  functions[webApi(us-central1)]: Successful update operation.
i  hosting[surveyplus-effd5]: finalizing version...
+  hosting[surveyplus-effd5]: version finalized
i  hosting[surveyplus-effd5]: releasing new version...
+  hosting[surveyplus-effd5]: release complete

+  Deploy complete!

【问题讨论】:

  • 请编辑问题以准确显示您正在采取的部署功能的步骤。将命令的输出复制到问题中,以便我们查看实际发生的情况。我们应该能够接受您的问题并自行重现该问题。
  • @DougStevenson 我已经添加了终端输出
  • 输出显示您的函数肯定正在部署。如果这与您在控制台中看到的不符,请联系 Firebase 支持以寻求帮助。 support.google.com/firebase/contact/support

标签: javascript node.js firebase google-cloud-functions firebase-hosting


【解决方案1】:

您的 Cloud Functions 已正确部署,因为我可以直接调用 /api/v1/test 路由就好了(在撰写本文时)。

但是,在您的 firebase.json 文件中,您的重写顺序不正确,如 docs 中突出显示的那样:

重要提示:rewrites 属性内,Hosting 响应将遵守由 first source glob 指定的规则,该规则捕获请求的路径。

{
  "hosting": {
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "/api/v1/**",
        "function": "webApi"
      },
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint"
    ],
    "source": "functions"
  }
}

因此,不是发送/api/v1/test 调用由您的云函数处理,而是错误地发送到您的 React 应用程序。交换订单应该可以解决这个问题。

另外注意,如果您打算将所有调用格式化并解析为 JSON,则应重新排序 main.use 调用。我也会使用 express Router 而不是完整的 express() 实例。

const main = express(); // full express instance
const app = express.Router(); // "child" express instance

main.use(bodyParser.json()) // parse body as json, then hand over to app
main.use('/api/v1', app)

【讨论】:

  • 谢谢,我感觉这与rewrites 有关,感谢您澄清这一点。我也做了你建议的改变
猜你喜欢
  • 1970-01-01
  • 2018-08-07
  • 2018-04-11
  • 2017-12-11
  • 2020-10-14
  • 1970-01-01
  • 2020-12-27
  • 2018-06-15
  • 2020-03-15
相关资源
最近更新 更多