如何返回嵌套的诺言?

时间:2019-01-30 14:11:09

标签: javascript firebase google-cloud-firestore google-cloud-functions

在尝试使用getCollections()检索子集合时,我在onCall函数中返回一个诺言时遇到问题

我有一个带有子集合的文档。每个子集合都有一个文档。 我正在尝试检索所有这些结构结构

data structure

我下面的代码具有2个结构,但是它们无法返回数据。我不了解\返回值时的结构

Public Sub Mail()
    Dim LastAuthor As String
        LastAuthor = ActiveDocument.BuiltInDocumentProperties("last Author")

        Dim Email As String
            Email = Replace(LastAuthor, " ", ".") & "@btrl.ro"


    Set OutApp = CreateObject("Outlook.Application")
    Set OutMail = OutApp.CreateItem(0)

    On Error Resume Next
    With OutMail
        .Display
        .Signature = "HTMLbody"
        .To = Email
        .CC = ""
        .BCC = ""
        .Subject = ActiveDocument.Name
        '.Body = "AVIZAT. Multumesc mult"
        '.Attachments.Add ActiveDocument.FullName
        ' You can add other files by uncommenting the following line.
        '.Attachments.Add ("C:\test.txt")
        ' In place of the following statement, you can use ".Display" to
        ' display the mail.
        .HTMLbody = "AVIZAT" & "<br>" & .HTMLbody

        Dim objDoc As Document
        Set objDoc = ActiveDocument
        objDoc.ExportAsFixedFormat _
        OutputFileName:=Replace(objDoc.FullName, ".docx", ".pdf"), _
        ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:=wdExportOptimizeForPrint, _
        Range:=wdExportAllDocument, Item:=wdExportDocumentContent
        ' Add the attachment first for correct attachment's name with non English symbols
        .Attachments.Add PdfFile.FullName

        .send
        MsgBox "E-mail trimis cu succes"

    Set OutMail = Nothing
    Set OutApp = Nothing

    End With

End Sub

控制台中的错误正在显示

const functions = require('firebase-functions');
const admin = require('firebase-admin')
admin.initializeApp()

exports.rs = functions.https.onCall( async (data, context) => {

  let cols = []
  return await new Promise( async (res, rej) => {
    let required_ref = admin.firestore().collection('required_services')
      .doc(data.user_id)


     return await required_ref.get()
      .then(async () => {
        let collections = await required_ref.getCollections()
        console.log('collections', collections)
        collections.forEach(async collection => {
          let docs = await collection.get()
          console.log('docs for collection', collection.id)
          docs.forEach(doc => {
            console.log('doc', doc)
            let doc_ = {
              id: doc.id,
              data: doc.data()
            }
            cols.push(doc_)
          })
        })
        console.log('inside async', cols)
        res(cols)

      })
  })
})

exports.requiresServices = functions.https.onCall( async (data, context) => {

  // const docs = () => {
    let required_ref = admin.firestore().collection('required_services')
      .doc(data.user_id)
    let cols = []

    return await required_ref.get()
      .then(async () => {
        let collections = await required_ref.getCollections()
        console.log('collections', collections)
        collections.forEach(async collection => {
          let docs = await collection.get()
          console.log('docs for collection', collection.id)
          docs.forEach(doc => {
            console.log('doc', doc)
            let doc_ = {
              id: doc.id,
              data: doc.data()
            }
            cols.push(doc_)
          })
        })
        console.log('inside async', cols)
        return cols
      })
})

exports.getRequiredServices = functions.https.onCall( (data, context) => {

    let required_ref = admin.firestore().collection('required_services')
      .doc(data.user_id)
    let cols = []

  let first = () => {
      console.log('inside first')
      let promise = new Promise( (res, rej) =>{
        required_ref.get().then( () => {
          return required_ref.getCollections().then(collections => {
            res(collections)
          })
        })
      } )
    return promise
  }

  let second = collections => {
    console.log('inside second')
      new Promise( (res, rej) => {
        collections.forEach(collection => {
          console.log('collection', collection)
          collection.get().then(docs => {

            return docs.forEach(doc => {
              console.log('each doc inside each collection first ', doc.id, '=>', doc.data())
              let doc_ = {
                id: doc.id,
                data: doc.data()
              }
              cols.push(doc_)
            })


          })
          console.log('return inside two, cols', cols)
        })
        res(cols)
      })
  }

  return first().then(second => second)//.then(third)

})

1 个答案:

答案 0 :(得分:1)

如果有人需要一些相关的东西,我就有这样的解决方案:

节点js

exports.getCollections = functions.https.onCall( async (data, context) => {

  let required_ref = admin.firestore().collection('required_services')
    .doc(data.user_id)

  return await required_ref.get()
    .then(async () => {
      let collections = await required_ref.getCollections()
      console.log('collections', collections)
      return {'cols':collections}
    })
    .catch( err => {
      throw new functions.https.HttpsError('failed to connect', err)
    })
})

客户端

let collections = this.$options.firebase.functions().httpsCallable('getCollections')

          collections({user_id: this.getUser().uid}).then(r => {
            debugger
            console.log('return from cloud function get required services', r)

            let collections_ = r.data.cols
            let docs = []
            collections_.forEach(async collection => {

              let ref_path = collection._referencePath.segments

              this.$options.firebase.firestore().collection(ref_path[0])
                .doc(ref_path[1]).collection(ref_path[2]).get()
                .then(async documents => {
                  let doc = await documents.docs[0].ref.get()

                  doc = {
                    id: doc.id,
                    path: doc.ref.path,
                    data: doc.data()
                  }

                  docs.push(doc)
                  console.log('doc path', documents.docs[0].ref.path)
                })
            })
          }).catch(err => console.error(err))

有效

编辑-基于Bergi建议

          let collections = this.$options.firebase.functions().httpsCallable('getRequiredServices')

          let r = await this.required_services = await collections({user_id: this.getUser().uid});
          debugger
          // console.log('return from cloud function get required services', r)

          let collections_ = r.data.cols
          let docs = [], docs_ = []

          for (let collection of collections_) {
            let path = collection._referencePath.segments

            let documents = await this.$options.firebase.firestore().collection(path[0])
                .doc(path[1]).collection(path[2]).get();
            console.log('__documents__', documents)

            for (let doc of documents.docs) {
              doc = await documents.docs[0].ref.get()
              doc = {
                id: doc.id,
                path: doc.ref.path,
                data: doc.data()
              }
              docs_.push(doc)
            }
          }
          console.log('docs_', docs_)