Koa Typescript 应用程序在任何 Firebase 数据库调用时挂起
Koa Typescript app hangs on any Firebase db call
我有一个用 typescript 编写的简单 koa
REST 服务,它有一个 GET
请求returns 来自 firebase 数据库的所有用户 在 db ref /user
.
应用程序收到请求并获取数据库引用,但它永远挂起当它应该获取值时。
这是我的 index.ts
文件:
import * as Koa from "koa";
import * as Router from "koa-router";
import * as json from "koa-json";
import * as bodyParser from "koa-bodyparser";
import firebase from "firebase";
import { config } from "./config";
const app = new Koa();
const router = new Router();
router.get("/users", async (ctx, next) => {
firebase.initializeApp(config.firebaseConfig);
const db = firebase.database();
const ref = db.ref("user");
console.log("got ref");
const snapshot = await ref.once("value");
console.log("got snapshot");
ctx.body = { users: snapshot.val() };
await next();
});
app.use(json());
app.use(bodyParser());
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log("Koa started on port 3000");
});
这是输出:
Koa started on port 3000
<-- GET /users
got ref
[2021-02-21T10:09:03.818Z] @firebase/database: FIREBASE WARNING: Namespace [masked-my-project]-dev-default-rtdb lives in a different region. Please change your database URL to https://[masked-my-project]-dev-default-rtdb.europe-west1.firebasedatabase.app (https://[masked-my-project]-dev-default-rtdb.firebaseio.com/)
这是我的 tsconfig.json
:
{
"version": "2.0.2",
"compilerOptions": {
"outDir": "./dist",
"lib": ["ES5", "ES6"],
"noImplicitReturns": true,
"sourceMap": true,
"target": "ES6",
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
"include": ["./src/**/*"],
"files": ["node_modules/typescript/lib/lib.es6.d.ts"],
"exclude": ["node_modules"]
}
package.json
:
{
"name": "koa-new",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"scripts": {
"dev": "./node_modules/.bin/tsc-watch --onSuccess \"node .\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "^8.2.0",
"firebase": "^8.2.9",
"koa": "^2.13.1",
"koa-bodyparser": "^4.3.0",
"koa-json": "^2.0.2",
"koa-logger": "^3.2.1",
"koa-route": "^3.2.0",
"koa-router": "^10.0.0",
"ts-node": "^9.1.1",
"typescript": "^4.1.5"
},
"devDependencies": {
"@types/dotenv": "^8.2.0",
"@types/firebase": "^3.2.1",
"@types/koa": "^2.13.0",
"@types/koa-bodyparser": "^4.3.0",
"@types/koa-json": "^2.0.18",
"@types/koa-logger": "^3.1.1",
"@types/koa-router": "^7.4.1",
"@types/node": "^14.14.31",
"tsc-watch": "^4.2.9"
}
}
.env
:
FIREBASE_API_KEY=[mask]
FIREBASE_AUTH_DOMAIN=[mask].firebaseapp.com
FIREBASE_DATABASE_URL=https://[mask]-default-rtdb.europe-west1.firebasedatabase.app
FIREBASE_PROJECT_ID=[mask]
FIREBASE_STORAGE_BUCKET=[mask].appspot.com
FIREBASE_MESSAGING_SENDER_ID=[mask]
FIREBASE_APP_ID=1:[mask]:web:[mask]
FIREBASE_MEASUREMENT_ID=[mask]
看起来我们的 config.ts
/config.js
有一个 databaseURL
形式的键:
https://[masked-my-project]-dev-default-rtdb.firebaseio.com/
错误消息说这应该是这种形式:
https://[masked-my-project]-dev-default-rtdb.europe-west1.firebasedatabase.app
如果您进行了更改,该消息应该会消失。
我没有将 Koa 与 Firebase 实时数据库结合使用的经验(我曾将 Koa 与 Firestore 结合使用来构建 REST API),所以请对此持保留态度。在我看来,就从实时数据库中获取相关数据而言,您所做的一切都是正确的。但是,我总是将要添加到响应正文中的任何对象字符串化,即:
const responseBody = {
'users' : snapshot.val()
}
ctx.body = JSON.stringify(responseBody);
此外,在您返回的对象中,我认为 users
应该在引号内(作为对象中的 string
类型键)。
最后,我也注意到你在使用koa-bodyparser
。 Firebase 已经解析了主体,并且 koa-bodyparser
无法处理已经解析的主体,这将是一个对象而不是未解析的字符串。这可能会导致您的呼叫挂起。而不要使用 koa-bodyparser
,而当您需要访问请求正文时,请使用 ctx.req.body
.
问题是 firebaseConfig
在 属性 中的数据库 url 命名为 databaseUrl
而不是 databaseURL
并且因为“Url" 不是大写的 firebase 以为我忘记添加它并默认为 https://[masked-my-project]-dev-default-rtdb.firebaseio.com/
而它需要是 https://[masked-my-project]-dev-default-rtdb.europe-west1.firebasedatabase.app
因此错误消息。
我有一个用 typescript 编写的简单 koa
REST 服务,它有一个 GET
请求returns 来自 firebase 数据库的所有用户 在 db ref /user
.
应用程序收到请求并获取数据库引用,但它永远挂起当它应该获取值时。
这是我的 index.ts
文件:
import * as Koa from "koa";
import * as Router from "koa-router";
import * as json from "koa-json";
import * as bodyParser from "koa-bodyparser";
import firebase from "firebase";
import { config } from "./config";
const app = new Koa();
const router = new Router();
router.get("/users", async (ctx, next) => {
firebase.initializeApp(config.firebaseConfig);
const db = firebase.database();
const ref = db.ref("user");
console.log("got ref");
const snapshot = await ref.once("value");
console.log("got snapshot");
ctx.body = { users: snapshot.val() };
await next();
});
app.use(json());
app.use(bodyParser());
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log("Koa started on port 3000");
});
这是输出:
Koa started on port 3000
<-- GET /users
got ref
[2021-02-21T10:09:03.818Z] @firebase/database: FIREBASE WARNING: Namespace [masked-my-project]-dev-default-rtdb lives in a different region. Please change your database URL to https://[masked-my-project]-dev-default-rtdb.europe-west1.firebasedatabase.app (https://[masked-my-project]-dev-default-rtdb.firebaseio.com/)
这是我的 tsconfig.json
:
{
"version": "2.0.2",
"compilerOptions": {
"outDir": "./dist",
"lib": ["ES5", "ES6"],
"noImplicitReturns": true,
"sourceMap": true,
"target": "ES6",
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
"include": ["./src/**/*"],
"files": ["node_modules/typescript/lib/lib.es6.d.ts"],
"exclude": ["node_modules"]
}
package.json
:
{
"name": "koa-new",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"scripts": {
"dev": "./node_modules/.bin/tsc-watch --onSuccess \"node .\"",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "^8.2.0",
"firebase": "^8.2.9",
"koa": "^2.13.1",
"koa-bodyparser": "^4.3.0",
"koa-json": "^2.0.2",
"koa-logger": "^3.2.1",
"koa-route": "^3.2.0",
"koa-router": "^10.0.0",
"ts-node": "^9.1.1",
"typescript": "^4.1.5"
},
"devDependencies": {
"@types/dotenv": "^8.2.0",
"@types/firebase": "^3.2.1",
"@types/koa": "^2.13.0",
"@types/koa-bodyparser": "^4.3.0",
"@types/koa-json": "^2.0.18",
"@types/koa-logger": "^3.1.1",
"@types/koa-router": "^7.4.1",
"@types/node": "^14.14.31",
"tsc-watch": "^4.2.9"
}
}
.env
:
FIREBASE_API_KEY=[mask]
FIREBASE_AUTH_DOMAIN=[mask].firebaseapp.com
FIREBASE_DATABASE_URL=https://[mask]-default-rtdb.europe-west1.firebasedatabase.app
FIREBASE_PROJECT_ID=[mask]
FIREBASE_STORAGE_BUCKET=[mask].appspot.com
FIREBASE_MESSAGING_SENDER_ID=[mask]
FIREBASE_APP_ID=1:[mask]:web:[mask]
FIREBASE_MEASUREMENT_ID=[mask]
看起来我们的 config.ts
/config.js
有一个 databaseURL
形式的键:
https://[masked-my-project]-dev-default-rtdb.firebaseio.com/
错误消息说这应该是这种形式:
https://[masked-my-project]-dev-default-rtdb.europe-west1.firebasedatabase.app
如果您进行了更改,该消息应该会消失。
我没有将 Koa 与 Firebase 实时数据库结合使用的经验(我曾将 Koa 与 Firestore 结合使用来构建 REST API),所以请对此持保留态度。在我看来,就从实时数据库中获取相关数据而言,您所做的一切都是正确的。但是,我总是将要添加到响应正文中的任何对象字符串化,即:
const responseBody = {
'users' : snapshot.val()
}
ctx.body = JSON.stringify(responseBody);
此外,在您返回的对象中,我认为 users
应该在引号内(作为对象中的 string
类型键)。
最后,我也注意到你在使用koa-bodyparser
。 Firebase 已经解析了主体,并且 koa-bodyparser
无法处理已经解析的主体,这将是一个对象而不是未解析的字符串。这可能会导致您的呼叫挂起。而不要使用 koa-bodyparser
,而当您需要访问请求正文时,请使用 ctx.req.body
.
问题是 firebaseConfig
在 属性 中的数据库 url 命名为 databaseUrl
而不是 databaseURL
并且因为“Url" 不是大写的 firebase 以为我忘记添加它并默认为 https://[masked-my-project]-dev-default-rtdb.firebaseio.com/
而它需要是 https://[masked-my-project]-dev-default-rtdb.europe-west1.firebasedatabase.app
因此错误消息。