Firebase ios快照为.childRemoved返回null

时间:2017-02-07 21:40:39

标签: ios swift firebase firebase-realtime-database

我刚开始使用Swift和Swift一起使用,并有一个示例消息节点。我添加了包含文本和用户名等的子邮件。我设置了安全规则,以便为每个.write和.read进行身份验证。我创建了一个观察者来观察这个甚至它正在发射,但它返回的快照是空的。我需要快照数据的原因是我可以从客户端删除该确切的消息。

数据节点结构:

{
"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 Code:

_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)
})

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

2 个答案:

答案 0 :(得分:0)

我能够通过创建查找键的查找功能来解决这个问题。我仍然不确定为什么索引(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
}

答案 1 :(得分:0)

你可能想以另一种方式解决这个问题:

每个快照(或子快照)都有一个密钥,这就是你应该在数组中查找的内容(table,dataSource等)

换句话说,当消息最初被加载时(例如,进入数据源),它们将位于一个键:值对

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

注意上面是字典,但它可以是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 = ""
}