【发布时间】:2020-06-09 04:44:27
【问题描述】:
我正在本地测试一组 Cloud Functions,并根据需要为数据库、Firestore、Hosting、PubSub 和 Functions 设置模拟器。我正在尝试执行以下操作:
- 在
functions/index.js文件中,我正在导入用作不同端点的 HTTP 触发器的模块。 - 我正在使用依赖注入 (DI) 来允许模块从
functions/index.js文件访问所有常见的依赖项。
到目前为止我的代码方法:
函数/index.js
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
const cors = require('cors');
const session = require('express-session');
const firestoreSession = require('connect-session-firebase')(session);
const cookieParser = require('cookie-parser');
const { validationResult } = require('express-validator');
const ref = admin.initializeApp({
databaseURL: 'http://localhost:8080',
credential: admin.credential.cert('path/to/credential.js')
});
// services
const UserService = require('./user/index')({
express, cookieParser, cors, ref,
session, firestoreSession, validationResult
});
exports.user = functions.https.onRequest(UserService);
HTTP 请求触发器是 express 的实例。我正在注入依赖项(如在 UserService 中),然后在 URL BASE_URL/user 下公开触发器。很少有其他类似的服务。在 UserService 中,我有以下内容:
module.exports = function({
express, cors,
session, firestoreSession,
cookieParser, validationResult, ref
}) {
const Validators = require('./validators');
const userserv = express();
userserv.use(cors({ origin: true }));
userserv.use(session({
name: 'user_session',
resave: true,
saveUninitialized: true,
secret: 'TOKEN_SECRET_HERE',
store: new firestoreSession({
database: ref.database()
})
}));
userserv.post('/login', (req, res, nxt) => {
res.json({
status: 200,
message: 'Logged In'
});
});
// ... other route handlers
return userserv;
};
functions/user/index.js
现在,当我启动模拟器时,一切正常。当我使用 curl 发送 POST 请求时,该函数会冻结,直到发生超时。这是 curl 请求的示例:
curl -X POST -H 'Content-Type:application/json' -d '{}' http://localhost:5001/<App>/<region>/user/login
当发生超时或手动停止模拟器时,我会看到预期的 JSON 响应。不确定是什么导致功能冻结。我的猜测可能与会话存储的数据库设置有关,这会导致函数进入无限循环的请求。一些建议将不胜感激。
注意:我使用 DI 是因为我想在一个文件中管理导入并在服务之间共享会话存储。我所看到的设置 firebase 会话存储的方式使用来自 admin.initializeApp 的应用程序引用,因此,很容易将其作为参数传递给所有导入的服务模块。
更新 1
问题肯定出在会话中间件上。注释掉functions/user/index.js 中的会话设置代码不会导致服务器在发出请求并按预期及时发送响应时冻结。
更新 2
查看调试日志后,database-debug.log 似乎“有问题”:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by io.netty.util.internal.ReflectionUtil (file:/home/zerocool/.cache/firebase/emulators/firebase-database-emulator-v4.3.1.jar) to field sun.nio.ch.SelectorImpl.selectedKeys
WARNING: Please consider reporting this to the maintainers of io.netty.util.internal.ReflectionUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
【问题讨论】:
-
添加一些调试日志,以准确了解您的函数能走多远。现在,你没有给自己任何暗示。
-
@DougStevenson 使用调试日志的输出更新了问题。此外,问题在于会话设置,因为将其注释掉可以解决问题。
-
如果这在部署时有效但在模拟器上无效,请在 Firebase CLI GitHub 上发布一个问题,其中包含有关如何构建一个无法按预期方式工作的完整、最小示例的说明。 github.com/firebase/firebase-tools
标签: node.js firebase express google-cloud-functions firebase-tools