Firebase ios快照为.childRemoved返回null

Firebase ios快照为.childRemoved返回null,ios,swift,firebase,firebase-realtime-database,Ios,Swift,Firebase,Firebase Realtime Database,我刚开始使用Firebase和Swift,并有一个示例消息节点。我添加包含文本和用户名等信息的子项。我为每个项设置了安全规则以进行身份验证。写入和读取。我创建了一个观测者来观察这一点,它正在启动,但它返回的快照为空。我需要快照数据的原因是,我可以从客户端删除确切的消息 数据节点结构: { "messages" : { "-KcM3SlAQXfjCz01waXF" : { "name" : "mgardner1994", "text" : "test23" },

我刚开始使用Firebase和Swift,并有一个示例消息节点。我添加包含文本和用户名等信息的子项。我为每个项设置了安全规则以进行身份验证。写入和读取。我创建了一个观测者来观察这一点,它正在启动,但它返回的快照为空。我需要快照数据的原因是,我可以从客户端删除确切的消息

数据节点结构:

{
"messages" : {
    "-KcM3SlAQXfjCz01waXF" : {
    "name" : "mgardner1994",
    "text" : "test23"
    },
    "-KcM3UKA_U7n2YwhlFeB" : {
    "name" : "mgardner1994",
    "text" : "test4"
    },
    "-KcMB_8Ec74HIQGL9adt" : {
    "name" : "mitchell_maler",
    "text" : "test5"
    },
    "-KcOC08kLUO-cEWLeICG" : {
    "name" : "mitchell_maler",
    "text" : "hello"
    },
    "-KcOC6ZWT6gyVi6pxGF8" : {
    "name" : "mitchell_maler",
    "text" : "test"
    }
}
}
规则:

{
 "rules": {
   "messages": {
     ".read": "auth != null",
     ".write": "auth != null"
     }
   }
}
Swift代码:

_refHandleDel = ref.child("messages").observe(.childRemoved, with: { (snapshot) -> Void in
    // TODO: Why is snapshot returning nil
    let index = self.messages.index(of: snapshot)
    self.messages.remove(at: index!)
    self.messagesTable.deleteRows(at: [IndexPath(row: index! , section: 0)], with: .automatic)
})

编辑:将数据结构添加到文本而不是图像中。

我可以通过创建查找键的查找函数来解决这个问题。我仍然不确定为什么索引(of)方法不起作用,但会继续挖掘

_refHandleDel = ref.child("messages").observe(.childRemoved) { (snapshot: FIRDataSnapshot!) in
        print(snapshot)

        // Never finds the object and returns nil
        let index = self.messages.index(of: snapshot)
        print(index ?? "no")

        // using the workaround method it finds the index using the key
        let index2 = self.indexOfSnapshotInArray(snapshot: snapshot, snapshotArray: self.messages)
        print(index2)

        if (index2 != -1) {
        self.messages.remove(at: index2)
        self.messagesTable.deleteRows(at: [IndexPath(row: index2 , section: 0)], with: .automatic)
        } else {
            print("Could not find message in array.")
        }
    }


func indexOfSnapshotInArray(snapshot: FIRDataSnapshot, snapshotArray: [FIRDataSnapshot]) -> Int {
    var index = 0
    for snap in snapshotArray {
        if (snapshot.key == snap.key) {
            return index
        }
        index += 1
    }
    return -1
}

您可能希望以另一种方式进行:

每个快照(或子快照)都有一个键,这就是您应该在数组(表、数据源等)中查找的内容

换句话说,当消息最初加载(例如加载到数据源中)时,它们将位于

messages
  -KcM3SlAQXfjCz01waXF (the key)
    name : "mgardner1994", (the values which are a dictionary)
    text : "test23"
理想情况下,您将得到这些键值对的数组

a[0] = key:value = -KcM3SlAQXfjCz01waXF: dictionary of children
a[1] = key:value = -KcM3UKA_U7n2YwhlFeB: dictionary of children
注意,上面是dictionary,但它可以是UserClass或ItemsClass

a[0] = aUser (UserClass)
a[1] = aUser (UserClass)
当您的应用程序收到删除事件时,它将作为快照传递key:value对。我们不关心值,但关心键,因为您可以在数组中找到该项的索引并将其删除。(通过ObjC NSPredicate查找匹配项)或。。。例如,如果您使用的是UserClass,则在Swift中类似于此

func handleChildRemoved(_ snapshot: FDataSnapshot! ) {

  let key = snapshot.key

  if let index = self.usersArray.indexOf({$0.firebaseKey == key}) {
      self.usersArray.removeAtIndex(index)
      self.usersTableView.reloadData()
  }
}
在这个例子中,我有一个UserClass

class UserClass {
   firebaseKey = ""
   userName = ""
}

可以在let index=行之前添加print(snapshot)并查看打印内容吗?根据规则,我假设正在执行删除操作的用户已通过身份验证。哦,请在你的问题中加入你的Firebase结构作为文本。链接可能会过期,图像不可搜索或复制/粘贴,因此如果我们需要回答结构更改,我们将不得不重新键入。你好,Jay,感谢您的关注。感谢您提供有关该图像的提示,我了解了如何从控制台导出json,并将其添加到问题中。我添加了print语句,它正在将其打印到控制台。现在它更有意义了,在监视程序中,它不会显示完整的快照对象,但在打印时会显示。这似乎是我的.index(of:)方法找不到它的问题。我认为这可以大大简化,从而完全消除这个问题。看看我的答案。非常感谢!是的,我的方向不是很有效,但是通过使用index(where:)方法,它变得简单多了。Swift将.indexOf重命名为.index(其中:)。