Firestore won't write documents if placed at bottom while returning multiple promises

Viewed 37

Firestore won't create documents if placed the return statement like this:

return Promise.all([
  res.status(200).send({
    method: 'sendMessage',
    chat_id, 
    text: `${field1Val}`, 
    parse_mode: 'HTML'
  }),
  admin.firestore().collection('colName').doc(`docName`).set({ "field1": field1Val }, { merge: true })
])

Though the below code will create the Doc:

return Promise.all([
  admin.firestore().collection('colName').doc(`docName`).set({ "field1": field1Val }, { merge: true }),
  res.status(200).send({
    method: 'sendMessage',
    chat_id, 
    text: `${field1Val}`, 
    parse_mode: 'HTML'
  })
])

I use the first format with realtime database and it works perfectly. I don't know why Firestore wants the privilege of being at top.

I have waited for 15+ mins and refreshed the page still no sign of the document.

PS: I had re-initialized the project and installed new npm modules too. Didn't help XD

The complete code which I don't think is a problem cause the doc is created if I placed that command at top.

import * as functions from 'firebase-functions';
import * as express from 'express'
import * as cors from 'cors'
import admin = require('firebase-admin');
admin.initializeApp();

const bot = express()

bot.use(cors({ origin: true }))

bot.post('/', async (req, res) => {

const commandSliced: string = JSON.stringify(req.body.message.text)

  let userMsg: string = ''

  if (commandSliced.startsWith(`!text`)) { 
    userMsg = userCommandSliced.replace('!text', '')
    let exclmCmd_array: string[];
    msg_array = userEMsg.split(/\b\s+/, 2)

    const field1val= userMsg.replace(msg_array[0], '')

  return Promise.all([                
    res.status(200).send({
      method: 'sendMessage',
      chat_id, 
      text: `${field1val}`, 
      parse_mode: 'HTML'
    }), 
    admin.firestore().collection('colName').doc(`docName`).set({ "field1": field1Val }, { merge: true })                
  ]) 

})

EDIT: This worked as suggested by Doug.

return admin.firestore().collection('colName').doc(`docName`).set({ "field1": field1Val }, { merge: true }).then(() => {
  return res.status(200).send({
    method: 'sendMessage',
    chat_id,
    text: `${field1Val}`,
    parse_mode: 'HTML'
   })
 })      
1 Answers

The issues are that:

  1. res.status(200).send() doesn't return a promise, so it doesn't make sense to pass its value to Promise.all().
  2. res.status(200).send() also terminates the function immediately, which means that after it executes, you shouldn't expect other asynchronous code (like your Firestore update) to work at all.

What you should do instead is wait until the Firestore update completes (by using the promise it returns), then send the response as the very last thing in the function.

Related