当我尝试从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"
}
}
}
答案 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。