从Firebase删除时数组索引超出范围

时间:2019-11-12 04:43:55

标签: ios swift firebase firebase-realtime-database

当我尝试从Firebase中的一个孩子中删除一个节点时,它使我的代码崩溃,并给出了致命错误,提示“索引超出范围”。最终结果是从UID中删除与ID关联的数据。我已经附上了删除单元格的代码

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if (editingStyle == .delete) {
        var listOfUID = [String]()
        let ref = Database.database().reference().child(currentEmail!)

        ref.observe(.childAdded , with: { snapshot in
            if !snapshot.exists() {return}

            print(snapshot.key)

            let listOfUID = [snapshot.key]
            let name = listOfUID[indexPath.row]

            ref.queryOrdered(byChild: name ).queryEqual(toValue: name).observe(.childAdded, with: { (snapshot) in
                snapshot.ref.removeValue(completionBlock: { (error, reference) in
                    if error != nil {
                        print("There has been an error:\(error)")

                    }
                  data.remove(at: indexPath.row)
                  tableView.deleteRows(at: [indexPath], with: .left)
                })
            })
        })


    }
 }

let name = listOfUID[indexPath.row - 1]之类的某些原因也无法解决。

我也很高兴提及当前电子邮件中包含一个扫描仪的扫描仪,该扫描仪可以删除“。”。

我已经上传了数据库结构的设置方法

{
  "email@yahoocom" : {
    "-LtUztWPbQias7bh5C2L" : {
      "message" : "Didn’t",
      "teamName" : "jah"
    },
    "-LtUzumEkb2kjK4qeU6E" : {
      "message" : "D d",
      "teamName" : "did if"
    },
    "-LtVCbxDu6DqxWv7LHzp" : {
      "message" : "Cc’d",
      "teamName" : "xdfff"
    }
  },
  "nice@nicecom" : {
    "-LtSjXIKnKXKgp-XCzdP" : {
      "message" : "Test 2",
      "teamName" : "test 1"
    }
  }
}

1 个答案:

答案 0 :(得分:0)

有多种方法可以改进代码。由于这个问题有些含糊,我不得不在这里做出一系列假设。两个建议:

1)请勿将电子邮件地址用作节点密钥。您必须像提到的那样操纵它们,如果用户的电子邮件发生更改怎么办?您将必须仔细阅读,然后将其使用的每个位置写回去。使用.childByAutoId创建一个密钥,然后将发件人uid存储为子项。 uid总是引用该用户。使用.childByAutoId可以将密钥与数据解除关联,从而提供了更大的灵活性。

2)您无需查询节点即可将其删除。如果知道密钥,可以使用它来删除

这是您的用户和团队节点的外观:

users
   uid_0 //a users uid
      user_name: "Henry"
      email: "henry@thing.com"
      team: "team_0"

   uid_1 //another users uid
      user_name: "Leroy"
      email: "leroy@jenkins.com"
      team: "team_1"

teams
   team_0 //created with .childByAutoId
      team_name: "Cool Team"
   team_1
      team_name: "Awesome Team"

如果A组成为Cool Team,则可以在一个位置而不是每个用户处更改它。另外,您可以更改用户电子邮件,而不会影响应用程序中的任何其他代码或节点。

该问题中没有很多信息,但看起来其他用户发给用户的消息存储在通用侦查节点中

universalscout
   uid_0 //the uid of the user that's receiving the message
      message_id_0 //created with childByAutoId
         from_uid: "uid_1" //the uid of the user that sent the message
         msg: "Didn't"
      message_id_1
         from_uid: "uid_2"
         msg: "D d"
      message_id_2
         from_uid: "uid_3"
         msg: "Cc'd"

然后是一个类,用于保存消息数据并存储在支持tableView的dataSource中

class MessageClass {
   var msg_id = ""
   var from_uid = ""
   var msg = ""
)

,然后是一个类dataSource数组,将它们存储在其中

var myMessageArray = [MessageClass]()

因此,在阅读时,请遍历uid_0中的消息,读取每个消息,然后创建一个MessageClass,其中存储msg_id,其来源和消息。将每个类添加到dataSource数组。看来您知道如何从Firebase读取数据并填充dataSource,所以我将跳过该代码。

然后最后在删除时

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if (editingStyle == .delete) {
        let messageToDelete = myMessageArray[indexPath.row]
        let firebaseKey = messageToDelete.msg_id
        let ref = your_firebase.child("universalscout").child(this users uid).child(firebaseKey)
        ref.remove()
        //remove the row from the dataSource
        //reload the tableView
    }
 }

问题中未提及的一件事是,是否有观察者在监视已删除的节点。如果没有,那么上面的代码是不错的选择。如果是这样,您将需要更改从数据源中删除行的位置以及何时重新加载tableView。

相关问题