Я тестирую набор облачных функций локально и, при необходимости, имею эмуляторы для настройки базы данных, Firestore, Hosting, PubSub и Functions. Я пытаюсь сделать следующее:
- В файле
functions/index.js
я импортирую модули, которые используются в качестве триггера HTTP для разных конечных точек. - Я использую инъекцию зависимости ( DI) для предоставления модулям доступа ко всем распространенным зависимостям из файла
functions/index.js
.
Мой подход к коду пока:
функции / индекс. 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;
};
функции / пользователь / индекс. js
Теперь, когда я запускаю эмуляторы, все начинается нормально. Когда я отправляю запрос POST с помощью curl, функция просто останавливается, пока не истечет время ожидания. Вот пример запроса curl:
curl -X POST -H 'Content-Type:application/json' -d '{}' http://localhost:5001/<App>/<region>/user/login
Когда происходит тайм-аут или когда я вручную останавливаю эмуляторы, я вижу ответ JSON, как и ожидалось. Не уверен, что вызывает зависание функции. Полагаю, что-то связано с настройкой базы данных для хранилища сеансов, в результате чего функция вводит бесконечный l oop запросов. Некоторые предложения будут с благодарностью.
Примечание. Я использую DI, потому что хочу управлять импортом в одном файле, а также делиться хранилищем сеансов между службами. В способе, который я видел при настройке хранилища сессий firebase, используется ссылка на приложение из admin.initializeApp
, поэтому было бы легко передать это в качестве аргумента всем импортированным сервисным модулям.
Обновление 1
Проблема определенно связана с промежуточным программным обеспечением сеанса. Закомментирование кода настройки сеанса в functions/user/index.js
не приводит к зависанию сервера при выполнении запроса, и ответ отправляется быстро, как и ожидалось.
Обновление 2 После просмотра журналы отладки, это то, что казалось "проблематичным c" из 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