简体   繁体   English

为什么我的iOS应用程序无法从Firebase数据库读取?

[英]Why can't my iOS application read from Firebase Database?

I am currently having troubling reading and displaying my firebase database into a table list. 我目前在读取和将Firebase数据库显示到表列表中时遇到麻烦。 Below is the code I am using in its current View Controller. 以下是我在当前View Controller中使用的代码。

import UIKit
import Firebase
import FirebaseDatabase

class Buy_1: UIViewController, UITableViewDataSource, 
 UITableViewDelegate   {

var ref: DatabaseReference!
var databaseHandle: DatabaseHandle!

var postItem: [String] = []

@IBOutlet weak var TableView: UITableView!

@IBAction func goBackToOneButtonTapped(_ sender: Any) {
    performSegue(withIdentifier: "unwindSegueToVC1", sender: self)
}

override func viewDidLoad() {
    super.viewDidLoad()

    if FirebaseApp.app() == nil {
        FirebaseApp.configure()
    }

    //Set Self as tableview's data source and delegate
    self.TableView.delegate = self
    self.TableView.dataSource = self

    //Set the firebase reference
    ref = Database.database().reference()

    //Retrieve and listen for changes
    databaseHandle = ref?.child ("items").observe(.childAdded, with: { (snapshot) in

        //Convert value of data into string
        if let item = snapshot.value as? String
        {
            self.postItem.append(item)
            self.TableView.reloadData()
            self.ref?.keepSynced(true)
        }

        /*if let actualItem = item {
            //Appends data to our Item Array
            self.postItem.append(actualItem)

            //Reload TableView
            self.TableView.reloadData()
        }*/

    })
    // Do any additional setup after loading the view.
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

//MARK: - UITableView Delegate Methods


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return postItem.count
}

func tableView(_ TableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = TableView.dequeueReusableCell(withIdentifier: "BasicCell", for: indexPath)

    cell.textLabel?.text = postItem[indexPath.row]
    return cell

  }
}

Firebase数据库的屏幕截图

I do not receive any errors in the code so I am not sure what is wrong. 我没有在代码中收到任何错误,所以我不确定是什么错误。 & I have already set the database rules to true. &我已经将数据库规则设置为true。

Thank you. 谢谢。

You are observing .childAdded , which will trigger your block only when a child is being added to your observed tree of data. 您正在观察.childAdded ,仅当将子级添加到观察到的数据树中时,它才会触发块。 Change it to .value . 将其更改为.value

The issue in the code is that the children of items are not strings. 代码中的问题是项的子项不是字符串。 They in themselves are childSnapshots or key:value pairs. 它们本身就是childSnapshots或key:value对。

Here's some example code to read just the itemName from a structure similar to yours 这是一些示例代码,用于从类似于您的结构中读取itemName

items
   item_0
      itemName: "Josh"
   item_1
      itemName: "Screaming Eagle"
   item_2
      itemName: "Insignia"

and the code to print the key of each child node and the itemName 以及用于打印每个子节点的键和itemName的代码

let ref = self.ref.child("items")
ref.observe(.childAdded, with: { snapshot in
    if snapshot.exists() {
        let dict = snapshot.value as! [String: Any]
        let itemName = dict["itemName"] as? String ?? "No Item Name"
        print(snapshot.key, itemName)
    }
})

and the output 和输出

item_0 Josh
item_1 Screaming Eagle
item_2 Insignia

Note that I used a nil coalescing operator (the ??) to populate the itemName in case it was not found. 请注意,如果未找到itemName,我使用nil合并运算符(??)来填充itemName。

I am treating the value portion of the snapshot as a dictionary to allow you to access the child nodes but you could also accomplish that with .childSnapshot like this 我将快照的值部分视为字典,以允许您访问子节点,但您也可以使用.childSnapshot这样来完成

let i = snapshot.childSnapshot(forPath: "itemName").value as? String ?? "No Item"

The snapshot.exists is extraneous in this specific example but it should be used with reading by .value. 在此特定示例中,snapshot.exists是多余的,但应与按.value读取一起使用。

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

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