javascript - 如何返回嵌套的 Promise?

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

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

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

data structure

我的代码如下,有 2 个结构,但它们无法返回数据。我不理解返回值时的结构

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)

})

控制台中显示错误

Error: internal
    at new HttpsErrorImpl (index.cjs.js?001a:58)
    at _errorForResponse (index.cjs.js?001a:153)
    at Service.eval

最佳答案

我得到了这样的解决方案,如果有人需要相关的东西:

节点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_)

关于javascript - 如何返回嵌套的 Promise?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54442522/

相关文章:

javascript - 的下一个实例

javascript - 灯箱不调出放大的 img,只是白色框

javascript - Firebase 开关按钮

google-cloud-firestore - 被取代的 Cloud Datastore 上的 "DatastoreException: Missing or insufficient permissions"

javascript - JS事件碰撞

javascript - 如何在同一页面的div标签中打开链接?

firebase - 具有 Firebase 身份验证的 AWS AppSync

android - com.google.firebase.messaging.zza : can't find referenced class android. graphics.drawable.AdaptiveIconDrawable

javascript - 如何停止 componentWillUnmount 上的 Firestore `get` 查询

javascript - 云HTTPS函数: returning a Promise which is inside a Promisee