POST 请求使用 Firebase 函数表达 API 时出错
Error when POST request to express API with Firebase functions
我已经使用 Functions 和 Hosting 设置了一个 Firebase 项目,并使用 express 构建了一个简单的 API。我正在使用 Firebase 的本地模拟器套件。
我使用 Postman 发出以下请求
POST
http://localhost:5000/api/users
{
"name": "Kobe Bryant",
"email": "kobe@gmail.com"
}
我收到了
的回复
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /dreamkit-client-web/us-central1/api/api/users</pre>
</body>
</html>
状态代码为 404。另外,这就是日志所说的
00:53:17 I [hosting] Rewriting /api/users to http://localhost:5001/dreamkit-client-web/us-central1/api for local Function api
00:53:17 I function[api] Beginning execution of "api"
00:53:17 I hosting 127.0.0.1 - - [21/Nov/2020:05:53:17 +0000] "POST /api/users HTTP/1.1" 404 185 "-" "PostmanRuntime/7.26.8"
00:53:17 I function[api] Finished "api" in ~1s
我认为问题与 api/api/users
有关,但我确保没有重复的 /api
,因为我的函数源已经是 /api
。我该如何解决这个问题?
firebase.json
{
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
],
"source": "functions"
},
"hosting": {
"predeploy": [
"npm --prefix client run build"
],
"public": "client/build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/api{,/**}",
"function": "api"
},
{
"source": "**",
"destination": "/index.html"
}
]
},
"emulators": {
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"hosting": {
"port": 5000
},
"ui": {
"enabled": true
}
}
}
index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
//initialize firebase in order to access its services
admin.initializeApp();
const app = express();
// Init Middleware
app.use(express.json({ extended: false }));
// Define Routes
app.use('/users', require('./routes/users'));
app.get('*', (req, res) => {
res.send('Hello from the API');
});
exports.api = functions.https.onRequest(app);
users.js
const express = require('express');
const router = express.Router();
const admin = require('firebase-admin');
const { check, validationResult } = require('express-validator');
//initialize the database and the collection
const db = admin.firestore();
const usersRef = db.collection('users');
// @route POST users
// @desc Register a user
// @access Public
router.post(
'/',
[
check('name', 'Please add name').not().isEmpty(),
check('email', 'Please include a valid email').isEmail(),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { name, email } = req.body;
try {
let user = await usersRef.where('email', '==', email).get();
if (user.exists) {
return res.status(400).json({ msg: 'User already exists' });
}
user = { name, email };
const payload = await usersRef.add(user);
const id = payload.id;
res.json({ id });
} catch (err) {
console.error(err);
res.status(500).send('Server Error');
}
}
);
module.exports = router;
我认为您可能需要在此处包含“/api”前缀:
app.use('/api/users', require('./routes/users'));
我已经使用 Functions 和 Hosting 设置了一个 Firebase 项目,并使用 express 构建了一个简单的 API。我正在使用 Firebase 的本地模拟器套件。
我使用 Postman 发出以下请求
POST
http://localhost:5000/api/users
{
"name": "Kobe Bryant",
"email": "kobe@gmail.com"
}
我收到了
的回复<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot POST /dreamkit-client-web/us-central1/api/api/users</pre>
</body>
</html>
状态代码为 404。另外,这就是日志所说的
00:53:17 I [hosting] Rewriting /api/users to http://localhost:5001/dreamkit-client-web/us-central1/api for local Function api
00:53:17 I function[api] Beginning execution of "api"
00:53:17 I hosting 127.0.0.1 - - [21/Nov/2020:05:53:17 +0000] "POST /api/users HTTP/1.1" 404 185 "-" "PostmanRuntime/7.26.8"
00:53:17 I function[api] Finished "api" in ~1s
我认为问题与 api/api/users
有关,但我确保没有重复的 /api
,因为我的函数源已经是 /api
。我该如何解决这个问题?
firebase.json
{
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint"
],
"source": "functions"
},
"hosting": {
"predeploy": [
"npm --prefix client run build"
],
"public": "client/build",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "/api{,/**}",
"function": "api"
},
{
"source": "**",
"destination": "/index.html"
}
]
},
"emulators": {
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"hosting": {
"port": 5000
},
"ui": {
"enabled": true
}
}
}
index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
//initialize firebase in order to access its services
admin.initializeApp();
const app = express();
// Init Middleware
app.use(express.json({ extended: false }));
// Define Routes
app.use('/users', require('./routes/users'));
app.get('*', (req, res) => {
res.send('Hello from the API');
});
exports.api = functions.https.onRequest(app);
users.js
const express = require('express');
const router = express.Router();
const admin = require('firebase-admin');
const { check, validationResult } = require('express-validator');
//initialize the database and the collection
const db = admin.firestore();
const usersRef = db.collection('users');
// @route POST users
// @desc Register a user
// @access Public
router.post(
'/',
[
check('name', 'Please add name').not().isEmpty(),
check('email', 'Please include a valid email').isEmail(),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { name, email } = req.body;
try {
let user = await usersRef.where('email', '==', email).get();
if (user.exists) {
return res.status(400).json({ msg: 'User already exists' });
}
user = { name, email };
const payload = await usersRef.add(user);
const id = payload.id;
res.json({ id });
} catch (err) {
console.error(err);
res.status(500).send('Server Error');
}
}
);
module.exports = router;
我认为您可能需要在此处包含“/api”前缀:
app.use('/api/users', require('./routes/users'));