Expressjs маршрутизатор с Firestore разрешает перед получением данных - PullRequest
0 голосов
/ 06 мая 2020

РЕДАКТИРОВАТЬ: я обнаружил, что к сигнатуре функции можно добавить «asyn c», и, хотя вывод делает go в правильном порядке, я все равно получаю сообщение об ошибке, что я не могу установить заголовки после того, как они отправляются, хотя я их больше нигде не устанавливаю. Я изменил код, чтобы отразить это.

У меня проблема с моим API Google Firestore, использующим ExpressJS. Кажется, что результат отправляется до завершения запроса Firestore, и я не уверен, почему, поскольку в противном случае я ничего не делаю с res. Кажется, что запросы Firestore являются асинхронными c, но я не знаю, как заставить мою конечную точку ждать данных Firestore перед отправкой результатов. Вот мой код маршрутизатора:

router.post('/some_endpoint/get_something', async function (req, res) {
    console.log("Getting firestore data...")
    let db_data = null;
    let some_val = req.body.some_val;
    let colRef = db.collection("some_collection");
    await colRef.where("some_field", "==", some_val)
        .get()
        .then(function(querySnapshot) {
            querySnapshot.forEach(function(doc) {
                console.log("Still processing...")
                db_data = doc.data()
            })
            res.json({  <---- This is where it breaks
                status: 200,
                data: db_data
            })
        })
        .catch(function(error) {
            console.log("Error getting doc: ", error);
        })

    console.log("We're done!")
});

Это порядок вывода (ИЗМЕНИТЬ с новым порядком вывода):

Getting firestore data...
Still processing...
Error getting doc: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client...
We're done!

1 Ответ

0 голосов
/ 06 мая 2020

Сообщение об ошибке сообщает вам, что вы пытаетесь отправить несколько ответов, что недопустимо. Здесь ваш код вызывает res.json() много раз, по одному разу для каждого документа в результатах запроса:

            querySnapshot.forEach(function(doc) {
                console.log("Still processing...")
                res.json({
                    status: 200,
                    data: doc.data()
                })
            })

Вы должны вызвать res.json() только один раз с окончательным результатом для отправки клиенту, после вы закончите повторение результатов.

...