如何从 Cloud Firestore 上的对象中检索值?迅速

Posted

技术标签:

【中文标题】如何从 Cloud Firestore 上的对象中检索值?迅速【英文标题】:How retrieve values from an object on Cloud Firestore? Swift 【发布时间】:2019-02-06 06:20:01 【问题描述】:

我对 FirestoreFirebase 库还很陌生。有人可以解释我如何从我的object 中检索字段并将其存储在我的代码的变量中吗?我正在尝试从我的 Firestore 中的每个对象访问所有 latMinlatMaxlonMinlonMax,以及是否可以检索具有相同名称的每个字段(例如 @987654330 @来自位置 1 和 2)。我不知道这是否可能,或者是否有更好的方法来组织我的Firebase

这是我的 Cloud Firebase:Here is the image for my Firestore, requested in the comments.

place 1:  //This is an Object in my Firestore

  //Field = Number : Value ----> This is how object is orginazed 

  latMax : 39.727
  latMin : 39.726
  lonMax : -121.7997
  lonMin : -121.8003

place 2: 

  latMax : 39.7559
  latMin : 39.755
  lonMax : -122.1988
  lonMin : -122.1992

我能够毫无问题地访问对象,这是我用来读取 Firestore 上文档的功能:

import UIKit
import FirebaseFirestore
import Firebase
import CoreLocation

class SecondViewController: UIViewController, CLLocationManagerDelegate 

//Creating access to locationManager
var locationManager : CLLocationManager!

@IBOutlet weak var latLabel: UILabel!
@IBOutlet weak var lonLabel: UILabel!
@IBOutlet weak var place: UILabel!
@IBOutlet weak var placeImage: UIImageView!


//Storing the pass data that we got from the firt View
var lonStore = String()
var latStore = String()
var fireLon = String()
var fireLat = String()
var lonNumberStore = Double()
var latNumberStore = Double()
var fireLonMax = Double()
var fireLatMax = Double()
var fireLonMin = Double()
var fireLatMin = Double()


override func viewDidLoad() 


    //Here goes some code to display on the SecondViewController
    readArray()



func readArray() 

    let placeRef = Firestore.firestore().collection("places")
        placeRef.getDocuments  (snapshot, error) in
        guard let snapshot = snapshot else 
            print("Error \(error!)")
            return
        
        for document in snapshot.documents 
            let documentId = document.documentID
            let latMax = document.get("latMax") as! String //Getting a nil error
            print(documentId, latMax) //This print all objects

        
    

我遗漏了一些东西,但我知道,问题是我找不到任何关于在这种情况下我需要做什么的参考资料,我已经阅读了 50 次文档,但我找不到解决方案.感谢您花时间阅读我的帖子。

【问题讨论】:

Firwstore 不提供任何方法来获取文档特定字段的数据。您必须先获取集合的所有文档,然后才能获取所需的字段。 @Raj 我在获取文档后尝试了许多不同的方法来完成对字段的访问,但每次都返回 nil 或我的应用程序崩溃!我尝试的方式是像array[0] 等一样访问。 能否请您在调用函数的位置添加完整代码以及数据库截图 @Raj 我知道你的陈述是什么意思,但要澄清一点;您不必获取集合的 所有 文档 - 您可以获取单个文档然后访问它的字段。或者查询一组文档,您可以访问每个文档中的各个字段,或者检索所有文档并访问它们的字段。此处的示例Get Document 将检索单个“SF”文档的内容,可以访问该文档的各个字段。 @raj 我只是在我的代码上添加了我的 Firesbase 的屏幕截图以及一些小改动! 【参考方案1】:

一些澄清,因为 ios Firestore 文档,IMO,在许多领域都很轻松:有两种方法可以从文档字段中检索值(一旦获得文档)-使用 Firestore 方法(根据文档)并使用 Swift 的本地方法从字典中获取值。

let query = Firestore.firestore().collection("zipCodes").whereField("california", arrayContains: 90210)

query.getDocuments  (snapshot, error) in

    guard let snapshot = snapshot,
        error == nil else 
            return print("error: \(error!)")
    
    guard !snapshot.isEmpty else 
        return print("results: 0")
    

    for doc in snapshot.documents 

        // using firestore's convention
        if let array = doc.get("zipCodes") as? [Int] 
            if array.contains(90211) 
                // doc contains both zip codes
            
        

        // using swift's convention
        if let array = doc.data()["zipCodes"] as? [Int] 
            if array.contains(90211) 
                // doc contains both zip codes
            
        

    


就个人而言,为了安全性和可预测性,我会尽可能多地使用 Firestore 的框架,因此,使用get() 进行所有字段检索。

【讨论】:

【参考方案2】:

您的 readArray 代码非常接近。只需添加代码即可读取文档中的各个字段

func readArray()
   self.db.collection("places").getDocuments  (snapshot, err) in
       if let err = err 
           print("Error getting documents: \(err)")
        else 
           for document in snapshot!.documents 
              let docId = document.documentID
              let latMax = document.get("latMax") as! String
              let latMin = document.get("latMin") as! String
              let lonMax = document.get("lonMax") as! String
              let lonMin = document.get("lonMin") as! String
              print(docId, latMax, latMin, lonMax, lonMin)
           
       

原题中的问题是数据库的结构。这是一个与我的答案中的代码匹配的结构,并且更适合 OP 想要完成的任务。

问题中的结构在一个集合下列出了多个地方 - 没关系,但它将这些地方组合在一起。如果我们将其更改为每个集合只有一个位置,则可以更轻松地迭代它们并获取数据。

【讨论】:

我尝试访问您的代码后面的字段并返回 nil,我认为访问的字段有误,或者我可能遗漏了某些内容。我在我的帖子上编辑代码! @Robby AH - 好的。我看到了这个问题。数据库的结构方式是问题所在。您在每个集合下列出了多个地方,在这种情况下,我认为您想要一个代表一个地方的集合。我已经用一个更适合你想要做的事情的结构更新了我的答案。我发布的代码适用于该结构 @Robby 如果您真的想将所有地点列在一个集合下,可以这样做,但我认为将数据非规范化一级是合适的,因为***集合称为“地点” ' 无论如何,它的孩子应该是每个地方。【参考方案3】:

我认为您的场所模型引用了两个对象 bestBuy 和 house。因此,检索方法是仅从对象中检索数据并存储在对象中。意味着您可以直接设置plcaes模型中的所有数据。然后你可以调用 bestBuy 和 house 的 getter 方法来检索你想要的数据。这是一个示例代码(这里它只检索一个文档),但您可以通过迭代 for 循环并将每个文档转换为对象来对所有文档应用相同的代码:-

let docRef = db.collection("cities").document("BJ")

docRef.getDocument  (document, error) in
    if let city = document.flatMap(
      $0.data().flatMap( (data) in
        return City(dictionary: data)
      )
    ) 
        print("City: \(city)")
     else 
        print("Document does not exist")
    

但根据 firestore 文档,存储嵌套对象的最佳方法是创建一个子集合,然后将其存储在其文档中。

【讨论】:

这对我很有帮助,我现在唯一的问题是我想如何构建我的 Firestore。我必须找到构建数据库的最佳方法,并能够获得最佳结果!任何建议了解更多 Firestore 的知识!谢谢

以上是关于如何从 Cloud Firestore 上的对象中检索值?迅速的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Cloud Function 将数据从 Firebase Firestore 索引到 Elastic App Search?

如何使用 graphql 从 Firebase 使用 Flutter 从 Cloud Firestore 获取数据?

如何从 Cloud Firestore 中获取数据,其中 user.uid 等于 Flutter 中的文档 ID?

如何使用颤振和飞镖从 Cloud Firestore 检索特定数据?

Cloud Firestore:从 API 添加和更新数据

如何从 Cloud Firestore 数据库中获取 node.js 中的特定字段值?