【问题标题】:Struggling To Query Using getDocuments() in Firestore Swift努力在 Firestore Swift 中使用 getDocuments() 进行查询
【发布时间】:2020-08-30 16:08:54
【问题描述】:

这是我第一次使用 Firestore 查询,我正在努力解析数据。我通常在获取文档时使用相同的设置(这有效),但是当我将它附加到查询时它不起作用。

我正在尝试查询数据库中最常访问的商店,以便稍后将其设置为收藏。

我的代码:

func findFavouriteShop(completed: @escaping ([String]) -> Void)
{
    // Variables
    let dispatch = DispatchGroup()
    var dummyDetails = [String]()
    // References
    let db = Firestore.firestore()
    let userID = Auth.auth().currentUser?.uid
    let groupCollectionRef = String("visits-" + userID! )
    
    // Query the database for the document with the most counts
    dispatch.enter()
    db.collectionGroup(groupCollectionRef).order(by: "count", descending: true).limit(to: 1).getDocuments { (snapshot, error) in
        if let err = error {
            debugPrint("Error fetching documents: \(err)")
        }
        else {
            print(snapshot)
            guard let snap = snapshot else {return}
            
            for document in snap.documents {
                
                let data = document.data()
                
                // Start Assignments
                let shopName = data["shopName"] as? String
                let count = data["count"] as? String
                // Append the dummy array
                dummyDetails.append(shopName!)
                dummyDetails.append(count!)
         }
        dispatch.leave()
    }
    dispatch.notify(queue: .main, execute: {
    print("USER number of documents appended: \(dummyDetails.count)")
    completed(dummyDetails)}
    )
}

使用 Print 语句看起来好像保护语句将函数踢了出去。处理器没有到达 for 循环来执行分配。当我打印快照时,它返回一个空数组。

我确定我使用了错误的符号,但我不确定在哪里。

【问题讨论】:

  • 去掉orderBy()和limit()看看能不能拿到文件

标签: swift firebase google-cloud-firestore


【解决方案1】:

有很多要评论的,例如您选择集合组而不是集合(也许这就是您需要的),为什么您将结果限制在一个文档但又觉得需要查询集合,集合的命名(似乎很奇怪),获取多个商店但创建一个只返回一个商店的函数的查询,使用一个字符串作为可能应该是整数的计数属性,并使用字符串数组返回单个商店的多个组件而不是使用自定义类型。

也就是说,我认为这应该让您朝着正确的方向前进。我创建了一个自定义类型来向您展示我将如何开始这个过程,但是还有很多工作要做才能将它放在您需要的地方。但这是一个很好的起点。此外,由于您没有在文档解析中做任何额外的异步工作,因此不需要调度组。

class Shop {
    let name: String // constant
    var count: Int // variable
    
    init(name: String, count: Int) {
        self.name = name
        self.count = count
    }
}

func findFavouriteShops(completion: @escaping (_ shops: [Shop]?) -> Void) {
    guard let userID = Auth.auth().currentUser?.uid else {
        completion(nil)
        return
    }
    var temp = [Shop]()
    
    Firestore.firestore().collection("visits-\(userID)").order(by: "count", descending: true).limit(to: 1).getDocuments { (snapshot, error) in
        guard let snapshot = snapshot else {
            if let error = error {
                print(error)
            }
            completion(nil)
            return
        }
        for doc in snapshot.documents {
            if let name = doc.get("shopName") as? String,
                let count = doc.get("count") as? String {
                let shop = Shop(name: name, count: count)
                temp.append(Shop)
            }
        }
        completion(temp)
    }
}

您可以在此完成处理程序中返回 Result 类型,但在此示例中,我选择了 Shop 类型的可选数组(只是为了展示灵活性)。如果该方法返回nil 则有错误,否则数组中要么有商店要么没有。我也不知道您是在寻找一个商店还是多个商店,因为在您的某些代码中,您似乎想要一个,而在您的代码的其他部分,您似乎想要多个。

findFavouriteShops { (shops) in
    if let shops = shops {
        if shops.isEmpty {
            print("no error but no shops found")
        } else {
            print("shops found")
        }
    } else {
        print("error")
    }
}

【讨论】:

    猜你喜欢
    • 2020-08-25
    • 2018-11-16
    • 1970-01-01
    • 2021-07-21
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    相关资源
    最近更新 更多