I am trying to create a view controller displaying information of the clicked shop from a UITableView on the previous view controller. 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.
Also the id that you currently have is the userid, you need to retrieve the userid:
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?
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
:
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.