gpt4 book ai didi

swift - 如何从 Firebase 实时数据库中检索数据?

转载 作者:行者123 更新时间:2023-11-28 05:38:13 25 4
gpt4 key购买 nike

我试图从我的 firebase 数据库中检索 Firebase 中的数据集并将其呈现在 tableview 上。为了向前呈现它并能够查看我放入我的 firebase 服务器的数据

我已经尝试在 Stackoverflow 上使用多个问题,但似乎没有任何效果,日志错误似乎始终如一 Log Error


Firebase 树

Products {
dfkjsv4qc22aWE:{
name:"Apples",
weight:"1 Bag",
price:"$5.99",
imageUrl:"https://firebasestorage.googleapis.com/v0/b/randomImageapp.BlahBlask2233"
}

se04Fws444:{
name:"Flower",
weight:"Bouquet",
price:"$10.99",
imageUrl:"https://firebasestorage.googleapis.com/v0/b/randomImageapp.BlahBlask2233"
}
}

import UIKit
import Foundation
import Firebase
import FirebaseStorage
import FirebaseDatabase

class ProductListController: UIViewController {

@IBOutlet weak var productListTableView: UITableView!

var feeds = [ProductList]()
var dbRef :DatabaseReference!
var storage : Storage!

var dbRef: DatabaseReference!
var storage: StorageReference!

fileprivate var products: [ProductList] = []
{
didSet
{
productListTableView.reloadData()
}
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}

override func viewDidLoad() {
super.viewDidLoad()

productListTableView.dataSource = self
productListTableView.delegate = self

dbRef = Database.database().reference()
storage = Storage.storage().reference()

readProducts()
printProducts()
}

var productsArrayDataSource = [ProductList]()

func readProducts() {
let productsRef = self.dbRef.child("products") //self.ref points to my firebase
productsRef.observe(.childAdded, with: { snapshot in
let aProduct = ProductList(withSnapshot: snapshot)
self.feeds.append(aProduct)
})
}

func printProducts() {
for product in self.feeds {
print(product.id!, product.name!)
}
}

extension ProductListController: UITableViewDelegate, UITableViewDataSource {

func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return products.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ProductListCell") as!
ProductListCell

let details = products[indexPath.row]
cell.updateUI(with: details)

return cell
}
}

import Foundation
import UIKit
import Firebase
import FirebaseDatabase

class ProductList {
var name: String
var price: String
var weight: String
var imageUrl: String

init(withSnapshot: DataSnapshot) {
self.name = withSnapshot.childSnapshot(forPath: "name").value as? String ?? "No Name"
self.price = withSnapshot.childSnapshot(forPath: "price").value as? String ?? "No Price"
self.weight = withSnapshot.childSnapshot(forPath: "weight").value as? String ?? "No Weight"
self.imageUrl = withSnapshot.childSnapshot(forPath: "imageUrl").value as? String ?? "No ImageUrl"
}


import UIKit
import SDWebImage
import Firebase

class ProductListCell: UITableViewCell {

@IBOutlet weak var productImage: UIImageView!
@IBOutlet weak var productName: UILabel!
@IBOutlet weak var weight: UILabel!
@IBOutlet weak var price: UILabel!

func updateUI(with productList: ProductList) {
productName.text = productList!.name
price.text = productList!.price
weight.text = productList!.weight
productImage.text = productList!.imageUrl
}

override func layoutSubviews() {
super.layoutSubviews()
}
}

编辑:这就是我目前的错误 error 2它似乎比我的编码错误更像是一个 firebase 问题

最佳答案

让我看看是否可以让您朝着正确的方向前进。这个问题有几个部分,所以我深入到 Firebase 部分。如果在那之后 tableView 没有显示,那是 tableView 委托(delegate)问题,但看起来你的代码没问题。

要解决的第一个问题是 Firebase 结构 - 好吧,不是结构而是键。来自文档

If you create your own keys, they must be UTF-8 encoded, can be a maximum of 768 bytes, and cannot contain ., $, #, [, ], /, or ASCII control characters 0-31 or 127. You cannot use ASCII control characters in the values themselves, either.

因此您可以看到您的 key 中包含非法字符。通常最佳做法是允许 Firebase 使用 .childByAutoId() 创建 key .

看看 ProductList 类,它确实很好,但您可能还想跟踪 Firebase key 。因此,例如用户选择它,您将知道它是哪个项目。所以我只是添加了一个关键属性

class ProductList {
var key: String
var name: String
var price: String
var weight: String
var imageUrl: String

init(withSnapshot: DataSnapshot) {
self.key = withSnapshot.key
self.name = withSnapshot.childSnapshot(forPath: "name").value as? String ?? "No Name"
self.price = withSnapshot.childSnapshot(forPath: "price").value as? String ?? "No Price"
self.weight = withSnapshot.childSnapshot(forPath: "weight").value as? String ?? "No Weight"
self.imageUrl = withSnapshot.childSnapshot(forPath: "imageURL").value as? String ?? "No ImageUrl"
}
}

如评论中所述,子节点名称区分大小写,因此我还更新了代码以读取 imageURL 节点(以匹配您的结构)而不是 imageUrl .

然后是一个类数组来存储产品(如您的代码所示)

var feeds = [ProductList]()

然后是实际读取节点并填充提要数组的代码。

func readProducts() {
let productsRef = self.ref.child("Products") //self.ref points to my firebase
productsRef.observe(.childAdded, with: { snapshot in
let aProduct = ProductList(withSnapshot: snapshot)
self.feeds.append(aProduct)
})
}

这里需要注意的是,我们是使用observe.childAdded来读取的。 .childAdded 遍历每个子节点,最初一次一个,而 .observe 在该节点上留下一个观察者,该观察者将在添加新子节点时调用闭包中的代码。

稍后,我们想看看数组中有什么

func printProducts() {
for product in self.feeds {
print(product.key, product.name)
}
}

然后是调用 printProducts 时的输出

dfkjsv4qc22aWE Apples
se04Fws444 Flower

我从这个答案的结构中删除了非法字符,但 .childByAutoId() 又是你的 friend 。它始终有效、始终唯一并将 key 与其包含的数据分开。

最后想到的是:我什么时候重新加载我的 tableView。有几个选项,但一个是通过 .value 使用 .observeSingleEvent 读取数据一次,然后迭代代码中的子节点,填充数组(你的问题中的那种),然后重新加载 tableView。

第二个选项是利用 .value 事件总是在其他事件(例如 .childAdded)之后最后触发。因此,您可以使用 childAdded 来填充数组,但也可以添加一个 .value 事件,该事件将在添加所有子节点后触发,然后重新加载您的 tableView。 SO 上有许多该过程的示例。哦,现在有一个

Run Code after all children are added

关于swift - 如何从 Firebase 实时数据库中检索数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57863561/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com