Firebase数据库中的数据使用observeSingleEvent读取两次

时间:2017-11-06 16:29:18

标签: swift firebase firebase-realtime-database tableview

现在好几个小时我试图挖掘互联网论坛,试图找到问题的解决方案,我无法弄清楚发生了什么,所以我希望有人这里可以帮忙)

我有一个快速的应用程序,在我的一个视图控制器上,我想要做的是从Firebase数据库中检索数据并将其显示在我的tableview上。

在这里,您可以看到我的数据是如何组织的。 documentation

要获取tableview中的行数,我将其放入viewWillAppear部分

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("Number of contact TV: \(numberOfContact)")
        return numberOfContact
    }

然后,为了获得行数,我有了这个

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "contact-cell") as! EmergencyContactCell
        print("value of numberOfContact \(numberOfContact)")
        ref.child("users").child((user?.uid)!).child("emergencyContacts").observeSingleEvent(of: .value, with: { (snapshot: DataSnapshot) in
                print("snapshot value \(snapshot.value!)")

                for rest in snapshot.children.allObjects as! [DataSnapshot] {
                    guard let restDict = rest.value as? [String:Any] else { continue }
                    let firstName = restDict["contact_firstName"] as? String ?? ""
                    cell.UI_fullName.text = "\(firstName)"
                }
            })
        return cell
    }

填写我的tableview的单元格

Starting observing
Returning count
Number of contact TV: 0
Number of contact TV: 0
Number of contact TV: 0
Got snapshot
2
Number of contact TV: 2
value of numberOfContact 2
value of numberOfContact 2
snapshot value {
    1ArkUu6pMPZPgf3pGFAvvxHiTPFaf5Cl =     {
        "contact_firstName" = Kate;
        "contact_lastName" = Bell;
        "contact_phoneNumber" = "(555) 564-8583";
    };
    s8haDrYYAT9Y12ZnmAfE87pDyjDZGwjx =     {
        "contact_firstName" = Daniel;
        "contact_lastName" = Higgins;
        "contact_phoneNumber" = "555-478-7672";
    };
}
snapshot value {
    1ArkUu6pMPZPgf3pGFAvvxHiTPFaf5Cl =     {
        "contact_firstName" = Kate;
        "contact_lastName" = Bell;
        "contact_phoneNumber" = "(555) 564-8583";
    };
    s8haDrYYAT9Y12ZnmAfE87pDyjDZGwjx =     {
        "contact_firstName" = Daniel;
        "contact_lastName" = Higgins;
        "contact_phoneNumber" = "555-478-7672";
    };
}

而且我认为这就是它变坏的地方,因为在控制台中,无论我做什么,我都会不断显示2组数据,因此我的单元格总是填充相同的名称Firebase org of data。< / p>

这也是程序执行后我的控制台的捕获。

public enum ItemType {
    FRUITS("fru",PERISHABLE),
    VEGETABLES("veg",PERISHABLE),
    LIQUOURS("liq",LIQUIDS),
    SODAS("sod",LIQUIDS),
    FRESH_SQUEEZED_ORANGE_JUICE("orgj",LIQUIDS,PERISHABLE);

    private final String dbCode;
    private final EnumSet<ItemCategory> categories;
    private static final Map<ItemCategory,Set<ItemType>> INDEX_BY_CATEGORY = new EnumMap<>(ItemCategory.class);

    ItemType(String dbcode,ItemCategory... categories) {
      this.dbCode = dbcode;
      this.categories = EnumSet.copyOf(Arrays.asList(categories));
      //for (ItemCategory c:categories) {
      //  // Illegal Reference to Static Field!
      //  INDEX_BY_CATEGORY.put(c, this);
      //}
    }

    static {
      for (ItemCategory c:ItemCategory.values()) {
        INDEX_BY_CATEGORY.put(c, EnumSet.noneOf(ItemType.class));
      }
      for (ItemType t:values()) {
        for (ItemCategory c:t.categories) {
          INDEX_BY_CATEGORY.get(c).add(t);
        }
      }
    }

    public boolean is(ItemCategory c) {
      return INDEX_BY_CATEGORY.get(c).contains(this);
    }

    public Set<ItemType> getAll(ItemCategory c) {
      return EnumSet.copyOf(INDEX_BY_CATEGORY.get(c));
    }

    public String getDbCode() {
      return dbCode;
    }
}

提前感谢您的帮助:)

2 个答案:

答案 0 :(得分:0)

您的cellForRowAtIndex路径方法中存在错误。

 `ref.child("users").child((user?.uid)!).child("emergencyContacts").observeSingleEvent(of: .value, with: { (snapshot: DataSnapshot) in'

每次调用cellForRowAtIndexPath方法时,上面的行都会返回所有紧急联系人。

在你的for循环中,你总是循环并选择最后一个值。

您需要提取特定索引路径的值。

答案 1 :(得分:0)

我弄清楚了,我试图有一个完全不同的推理,它起作用了。我实际上使用了一个处理程序来管理这一切。我在这里发布我的代码,它可以帮助人们像几个小时前一样遇到同样的麻烦。

var emergencyContactList = [EmergencyContact]()


override func viewDidLoad() {
        super.viewDidLoad()
        ref = Database.database().reference()
        fetchUsers()
    }

func fetchUsers() {
        refHandle = ref.child("users").child((user?.uid)!).child("emergencyContacts").observe(.childAdded, with: { (snapshot) in
            if let dictionary  = snapshot.value as? [String:AnyObject] {
                print(dictionary)
                let emergencyContact = EmergencyContact()
                emergencyContact.setValuesForKeys(dictionary)
                self.emergencyContactList.append(emergencyContact)
                DispatchQueue.main.async {
                    self.UI_contactsTableView.reloadData()
                }
            }
        })
    }

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "contact-cell") as! EmergencyContactCell
        let _firstName = emergencyContactList[indexPath.row].contact_firstName ?? ""
        let _lastName = emergencyContactList[indexPath.row].contact_lastName ?? ""
        let _phoneNumber = emergencyContactList[indexPath.row].contact_phoneNumber ?? ""
        cell.UI_fullName.text = "\(_firstName) \(_lastName)"
        cell.UI_phoneNumber.text = "\(_phoneNumber)"
        return cell
    }

我有一个急速文件,紧急事件是紧急联络。

import Foundation

class EmergencyContact: NSObject {
    @objc var contact_firstName:String?
    @objc var contact_lastName:String?
    @objc var contact_phoneNumber:String?
}

现在它就像一个魅力! 感谢TheAppMentor花时间回答我:)