当前位置: 首页 > 知识库问答 >
问题:

如何从HttpScalable firestore函数获取JSON格式的documentSnapshot数组

井修雅
2023-03-14

因此,我想在我的客户机应用程序上使用HttpScalable云函数加载firestore文档。在我使用典型的getDocuments函数加载文档并返回一组简单的JSON格式快照之前,如下所示:

Firestore.firestore().collection("users").getDocuments { (snapshot, err) in
if let err = err{
                print("Failed to load data from html" target="_blank">firebase:", err)
                return
            }
snapshot?.documents.forEach({ (documentSnapshot) in
// documentSnapshot.data() is in JSON format
...
    }
}

现在我想加载我的文档,并返回一个HttpScalable云函数。因此,我的云功能运行良好,可以返回文档数据。但我遇到的问题是函数的返回格式。我从云功能接收的数据格式如下:

(
        {
        index = 34;
        field1 =         (
            "yes",
            "no",
            "maybe"
        );
        field2 = 26;
        brand = Puma;
        color = "marshmallow-natural";
        EcoFriendly = 1;
     },
      {
        index = 12;
        field1 =         (
            "oui",
            "non",
            "peut-être"
        );
        field2 = 21;
        brand = Nike;
        color = "red";
        EcoFriendly = 0;
     }
...
)

我通过如下调用函数来观察这一点:

functions.httpsCallable("smartShoeFinder").call([
        "vector": fireV[0]]) { (result, error) in
          
            if let error = error as NSError? {
            // Handle error
          }
            print(result?.data)
            //The following is my attempt towards extracting the data and
            // converting it to an array of JSON:
            let requestResult = result!.data
            if let swiftArray  = result!.data as! NSArray as? [Any] {
                print(swiftArray[0])
            }
            
  }

我希望我的数据是JSON数组,如下所示:

[["index": 34, "field1": ["yes", "no", "maybe"], "field2": 26, "brand": "Puma", "color" = "marshmallow-natural", "shoeEcoFriendly": 1], 
["index": 12, "field1": ["oui", "non", "peut-être"], "field2": 21, "brand": "Nike", "color" = "red", "shoeEcoFriendly": 1]]

以前的格式是一个简单的JSON字典数组(如上所述),可以轻松地转换到我的不同客户端对象。现在它是一个__NSArrayM(显然是一个NSMutableArray)。所以你知道我是否可以在JSON数组中获得我的http psCallable fi恢复函数的返回吗?就像下面的请求一样:

Firestore.firestore().collection("users").getDocuments{ (snapshot, err) in
    snapshot?.documents.forEach({ (documentSnapshot) in
    documentSnapshot.data() // I'd like it in this format
    }
}

函数返回一个由以下数据组成的数组(TypeScript):

const db = admin.firestore();
export const smartShoeFinder = functions.https.onCall(async (data, context) => {
let outputDocuments = new Array()
const collection = await db.collection('collection')
const notVisited = [1,32,13,44,15,26]
for (const index of notVisited){
    console.log(index)
    const snap = await collection.where("index", "==", index).get()
    if (snap.size == 0){
       continue
       }
    const onlyDoc = snap.docs[0].data
    outputDocuments.push(onlyDoc) // Populating the array with the wanted documents
  }
// Now returning promise to the client
.then(() => {
    return new Promise((resolve, reject) => {
        resolve(outputDocuments)
    })
})
.catch(err => console.log(err))
})

其中outputDocuments是文档数据的数组。

有更好的方法吗?

共有1个答案

白烨煜
2023-03-14

我是一名JavaScript开发人员,对Swift的知识有限,但您可以将代码简化为:

const db = admin.firestore();

exports.smartShoeFinder = functions.https.onCall(async (data, context) => {
    // FROM CLIENT AS AN ARRAY OF INTEGERS
    const notVisited = data.notVisited;     

    function getDoc(index){
        // RETURNS THE QUERY WHICH IS ALREADY A PROMISE SO NO NEED TO WRAP IT
        return db.collection('collection').where("index", "==", index).get().then(colSS=>{
            if (r.empty){
                return {
                    isEmpty: true
                };
            }
            else{
                return {
                    isEmpty: false,
                    doc: r.docs[0].data()
                };
            }
        }).catch(e=>{
            console.log("QUERY ERROR: " + e.message);
        })
    }
    // STORES ALL QUERIES IN AN ARRAY OF PROMISES
    let processes = notVisited.map(index=>{
        return getDoc(index);
    })
    // USE Promise.all() TO RESOLVE ALL THE PROMISES IN PARALLEL
    return Promise.all(processes).then(result=>{
        // FILTER OUT THE NON EMPTY ONES AND EXTRACT THE DATA.
        return result.filter(query=>{
            return !query.isEmpty;
        }).map(query=>{
            return query.doc;
        })
    })
})

或者,如果您的未访问索引数组长度在10个元素以内,则可以进一步简化,使用array-hols-any查询并将索引字段转换为单个元素数组(您需要为每个文档预先准备),如:

const db = admin.firestore();

exports.smartShoeFinder = functions.https.onCall(async (req, context) => {
    return await db.collection("collection").where("index", "array-contains-any", data.notVisited).then(colSS=>{
        return colSS.docs.map(docSS=>{
            return docSS.data();
        })
    })
})
 类似资料:
  • 我试图在我的应用程序中创建一个搜索功能,它基本上根据用户的查询(如任何产品名称)过滤json数据(如产品列表),并显示最接近的结果。我已经成功实现了这个搜索栏和过滤逻辑,但它是在我的应用程序中我的产品列表的本地json数据上工作的。我想要的是从网络调用(http调用)中获取json数据,然后进行过滤。但是我的实时数据库中有数据,我不知道如何以json格式检索它们。我可以设置云函数(节点js)来将j

  • 你好,我来自从URL获取JSON对象 我试着去买一顶帽子- 有人能告诉我我做错了什么吗?

  • 如何使用方法将数据检索到数据库中,我创建了一个从外部服务api检索数据的方法-可以显示该方法,但我在创建将检索到的数据发送到数据库的适当方法时遇到了问题。 方法从外部api检索数据: 我准备了一个存储库和一个实体来创建一个数据库(创建了数据库,但没有填充数据) 我目前创建了一个POST方法,但它不允许检索和保存数据(逻辑不好?)。 DTO型号: 允许您保存数据的服务。 因此,我有一个问题,就是如何

  • 问题内容: 我正在与集成的android应用程序上工作。我正在使用fql查询从Facebook获取信息。我的fql方法是 myjson对象具有我想要的所有信息。像这样 问题是如何将该信息存储到不同的阵列中? 请为此修改一些代码。 问题答案: 检查http://www.androidhive.info/2012/01/android-json-parsing- tutorial/

  • 问题内容: 我已经签出了很多页面,但是大多数教程和脚本使用这种JSON输出类型返回错误代码。那么,如何才能从Java中的JSON中提取数据? 问题答案: 如果要使用Gson,则首先声明用于容纳每个元素和子元素的类: 然后,声明一个最外层元素的数组(因为在这种情况下,JSON对象是一个JSON数组),并对其进行分配: 然后,您只需访问的元素。 要记住的重要一点是,您声明的属性的名称和类型应与JSON