【问题标题】:What could cause a Swift/Firebase app to act up the first time it is installed and never again?什么会导致 Swift/Firebase 应用程序在第一次安装时就运行起来,然后再也不运行了?
【发布时间】:2021-08-02 14:43:38
【问题描述】:

什么是第一次不起作用?:

我获取的数据库条目的显示顺序

我正在运行这个

1st part In ViewDiDLoad

let thisUserRef = Database.database().reference().child("users").child(uid)
let myPeopleRef = thisUserRef.child("likers")
myPeopleRef.queryLimited(toLast: 30).observeSingleEvent(of: .value, with: { snapshot in
    let userArray = snapshot.children.allObjects as! [DataSnapshot]
    for person in userArray.reversed() where uid == Auth.auth().currentUser?.uid  {
        let personUid = person.value as! String
        self.printPersonInfo(uid: personUid) //// this calls a DispatchQueue.main.async that appends the data in the array and reloads
    }
})

  func printPersonInfo(uid: String) {
        print(uid)
        let usersRef = Database.database().reference().child("users")
        let thisUser = usersRef.child(uid)
        thisUser.observeSingleEvent(of: .value, with: { snapshot in
            let xx = snapshot.childSnapshot(forPath: "xx").value as? String ?? "No Entry"
            let yy = snapshot.childSnapshot(forPath: "yy").value as? String ?? "No Entry"
            let rr = snapshot.childSnapshot(forPath: "rr").value as? String ?? "No Entry"
            let zz = snapshot.childSnapshot(forPath: "zz").value as? String ?? "No Entry"
            let ll = snapshot.childSnapshot(forPath: "ll").value as? String ?? "No Entry"
            let p = Usery(xx: xx, yy: yy, rr: rr, zz: zz, ll: ll)
            self.person.append(p)
            print(self.person, "person")
            self.table.reloadData()
        })
}
//////this gets the various data elements of the users that get displayed. 
///////So to summarize, the query determines which users get displayed. This func determined which data of those users gets displayed.

过去 30 年的数据库整体示例

user K
user B
user F
user G
user K
user B
user K
.....

唯一不起作用的情况是您第一次安装干净的应用程序。那么它的显示顺序是

user K
user K
user B
user B
user F
user G

JSON

users 
  uid 
   likers
      chailbyAutoID: uid1
      chailbyAutoID: uid2
  

【问题讨论】:

  • 问题中的代码与输出的相关性不清楚。 self.printPersonInfo(uid: personUid) 与输出有什么关系? uid 是独一无二的,所以那些似乎不是 uid 的。你能澄清一下问题、代码和输出吗?
  • @Jay 我的错。我忘了在 self.printPersonInfo(uid: personUid) 中发表评论。我刚刚这样做并将其代码添加到问题中。基本上,它调用 DispatchQueue.main.async 将数据附加到数组中并重新加载。你是对的,那些看起来不像 UID。我只是想展示它们错误显示的形式。我刚刚向他们添加了 user k 等,以便更清楚地了解他们是什么。
  • 你不需要这个DispatchQueue.main.async{ - Firebase 闭包是异步的,UI 更新总是在主线程上调用。这确实是主要问题,也是造成混乱的原因。此外,您将首先要填充数组,然后重新加载您的 tableview。否则它会一遍又一遍地重新加载,这会导致闪烁。
  • 我删除了DispatchQueue.main.async{},但在首次安装时仍然如此。我觉得有趣的是,将它按正确的顺序排列,只是将经常性用户集中在一起
  • 你能格式化和更新你的代码吗?为了得到答案,我们需要看看你在哪里?我仍然认为这是一个异步问题。

标签: ios swift firebase firebase-realtime-database firebase-queue


【解决方案1】:

一种可能的解决方案是使用 DispatchGroups 来控制数据的加载,从而控制填充类 var 数组的顺序。

在此示例中,我们将从用户节点读取所有用户 uid 并填充一个数组。它看起来像这样

users
   uid_0
      name: "Wilbur"
   uid_1:
      name: "Orville"

然后我们将返回并使用 array.reversed() 从该节点重新读取其他用户数据,以便它们以相反的顺序填充结果数组。我们需要一个类来存储每个用户数据,然后需要一个类数组来存储所有读入的用户。这是类 vars

struct PersonClass {
   var uid = ""
   var name = ""
}

var personArray = [PersonClass]()

以及以相反顺序填充它们的代码

func readUserDataUsingDispatch() {
    let ref = self.ref.child("users") //self.ref points to my firebase
    ref.observeSingleEvent(of: .value, with: { snapshot in

        //this just builds and array of user id's - we'll iterate through them to read the rest of the data
        let idArray = snapshot.children.allObjects as! [DataSnapshot]
        var allKeys = [String]()
        for userSnap in idArray {
            allKeys.append( userSnap.key ) //[uid_0, uid_1] etc
        }

        let group = DispatchGroup()

        for uid in allKeys.reversed() {
            group.enter()
            let thisUser = ref.child(uid)

            thisUser.observeSingleEvent(of: .value, with: { userSnapshot in
                let name = userSnapshot.childSnapshot(forPath: "name").value as! String
                let person = PersonClass(uid: uid, name: name)
                self.personArray.append(person)
                print("added uid")
                group.leave()
            })
        }

        group.notify(queue: .main) {
            print("done")
        }
    })
}

当你运行代码时,这是输出,表明数据已加载

added uid
added uid
done

然后在打印类 var personArray 时,它是倒序的用户。

uid_1 Orville
uid_0 Wilbur

【讨论】:

  • 谢谢。还没有开始工作。后者(大多数 30 个中的最后 10 个仍然捆绑在一起)。我认为直到for uid in allKeys.. 部分你的答案和我的代码是一致的。我使用`snapshot.children.allObjects 作为! [DataSnapshot] ` 其中包括 childbyAutoID 和 key,而您的答案仅使用 key。但我认为这不是错误的来源。我认为这是之后的部分。对于该部分,我无法将我的代码格式化为接近您的代码,因为我需要调用为需要显示的用户获取数据的函数。他们的 uid 在当前用户 uid 下。我在 Q 中添加了 JSON。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 2015-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-23
  • 1970-01-01
相关资源
最近更新 更多