简体   繁体   English

无法使用Swift从Firebase检索数据

[英]Can't retrieve data from Firebase with Swift

I am trying to create a view controller displaying information of the clicked shop from a UITableView on the previous view controller. 我正在尝试创建一个视图控制器,以显示前一个视图控制器上的UITableView中被点击的商店的信息。 However, I cannot retrieve data in the new view controller and I don't know how to solve this issue. 但是,我无法在新的视图控制器中检索数据,也不知道如何解决此问题。 Here is my database structure. 这是我的数据库结构。 Thank you for the help. 感谢您的帮助。 数据库结构

import UIKit
import Firebase
import FirebaseDatabase

class ShopViewController: UIViewController {    
    var name :String? // This is the name of the cell clicked on the previous viewcontroller

    var ref: DatabaseReference!
    @IBOutlet weak var shopName: UILabel!    
    @IBOutlet weak var shopType: UILabel!    
    @IBOutlet weak var imageView: UIImageView!

    override func viewDidLoad() {
        shopName.text = name

        let ref = Database.database().reference().child("shops").childByAutoId().child(name!).child("Details")

        ref.observe(.childAdded, with: { snapshot in            
            let snapshotValue = snapshot.value as! NSDictionary
            let imageUrlString = snapshotValue["imageURL"] as! String
            print(imageUrlString)
            let shoptype = snapshotValue["type"] as! String
            self.shopType.text = shoptype            
        })
    }
}

The reference that you have is wrong, childByAutoId() is used to generate a unique id in your database. 您的引用有误, childByAutoId()用于在数据库中生成唯一的ID。

Also the id that you currently have is the userid, you need to retrieve the userid: 另外,当前拥有的ID是用户ID,您需要检索该用户ID:

let user = Auth.auth().currentUser
let uid = user.uid

then the location should be: 那么位置应该是:

let ref = Database.database().reference().child("shops").child(uid).child("Eat").child("Details")

So there's a couple of issues here, first off is your data structure. 所以这里有几个问题,首先是您的数据结构。

Something along these lines would be much easier to read from. 遵循这些思路的内容将更容易阅读。 You shouldn't need the name field as far as I can tell, and is there a requirement to have the details nested? 据我所知,您不需要name字段,是否有嵌套详细信息的要求?

在此处输入图片说明

Reading the data 读取数据

Next up, you can refactor your data reference code. 接下来,您可以重构数据参考代码。 I'd firstly recommend extracting the logic into its own method rather than having it directly in viewDidLoad : 我首先建议将逻辑提取到其自己的方法中,而不是直接将其包含在viewDidLoad

var ref: DatabaseReference!

override func viewDidLoad() {
    shopName.text = name
    self.ref = Database.database().reference()
    getShopDetails()
}

func getShopDetails() {
  guard let shopName = name else { return }
   ref.child("shops").child(shopName).observe(.childAdded, with: { snapshot in         
        guard let shop = snapshot.value as? [String: AnyObject] else { return }

        let imageUrlString = shop["imageURL"] as! String
        print(imageUrlString)
        let shoptype = shop["type"] as! String
        self.shopType.text = shoptype            
    })
}

I've modified to set the database reference value as otherwise this would crash if you tried to use it elsewhere. 我已修改为设置数据库参考值,否则,如果您尝试在其他地方使用它,则会崩溃。 I've also added a couple of guard statements to minimise the number of explicit unwraps. 我还添加了一些保护声明,以最大程度地减少显式展开的次数。

I can't comment on your list code, but have you considered doing the call for all of the shops in this, and mapping the result to a data object, which you can then use to display the data in the screen we're detailing here, rather than doing a separate query every-time you open a detail screen. 我无法评论您的列表代码,但是您是否考虑过对此中的所有商店进行呼叫,并将结果映射到数据对象,然后可以将其用于在我们正在详述的屏幕中显示数据在这里,而不是每次打开详细信息屏幕时都进行单独的查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM