Firebase 托管 + 云功能
Firebase Hosting + Cloud Function
难以部署我的功能以及托管。
问题是,我已经让它们在单独的分支上独立工作,但是..当尝试集成托管和我的云功能时,我的云功能似乎没有部署。我的终端没有收到任何错误,当我在 firebase 控制台中单击 'functions' 时,它是默认屏幕,就好像没有部署任何功能一样。
这是我的 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"
}
}
这是我的 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)
})
)
})
Hosting + functions 分支,我输入 '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!
On cloud function only branch
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!
您的 Cloud Functions 已正确部署,因为我可以直接调用 /api/v1/test
路由(在撰写本文时)。
但是,在您的 firebase.json
文件中,重写的顺序不正确,如 docs 中突出显示的那样:
Important: Within the rewrites
attribute, the Hosting response will obey the rule specified by the first source
glob that captures the requested path.
{
"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
调用以供您的 Cloud Function 处理,而是错误地发送到您的 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)
难以部署我的功能以及托管。
问题是,我已经让它们在单独的分支上独立工作,但是..当尝试集成托管和我的云功能时,我的云功能似乎没有部署。我的终端没有收到任何错误,当我在 firebase 控制台中单击 'functions' 时,它是默认屏幕,就好像没有部署任何功能一样。
这是我的 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"
}
}
这是我的 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)
})
)
})
Hosting + functions 分支,我输入 '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!
On cloud function only branch
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!
您的 Cloud Functions 已正确部署,因为我可以直接调用 /api/v1/test
路由(在撰写本文时)。
但是,在您的 firebase.json
文件中,重写的顺序不正确,如 docs 中突出显示的那样:
Important: Within the
rewrites
attribute, the Hosting response will obey the rule specified by the firstsource
glob that captures the requested path.
{
"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
调用以供您的 Cloud Function 处理,而是错误地发送到您的 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)