【问题标题】:How to remove value from array in Firebase when I delete the row from tableview?当我从 tableview 中删除行时,如何从 Firebase 中的数组中删除值?
【发布时间】:2021-07-01 08:57:18
【问题描述】:

我有从 Firebase 显示数组的 tableview。当我从 tableview 中删除行以从 Firebase 数组中删除值时,我需要。

这是我的代码,但它给了我一条错误消息:

无法将“NSNull”(0x114b66dd0)类型的值转换为“NSArray”(0x114b66448)。 2021-04-05 15:32:20.045614+0200 我的婚礼 [8355:287880] 无法将“NSNull”(0x114b66dd0)类型的值转换为“NSArray”(0x114b66448)。 (lldb)

我是 swift 新手,所以我不熟悉。

 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    
    if editingStyle == .delete {
        let guest = guestList[indexPath.row]
        refGuests = Database.database().reference().child("userInfo").child(uid!).child("tables").child("guestsOnTable")
        refGuests.observe(.value) { (snapshot) in
            if let guestsOnTable = snapshot.value as! [String]? {
                for i in 0..<guestsOnTable.count{
                    if guestsOnTable[i] == self.uid {
                        self.refGuests.child("userInfo").child(self.uid!).child("tables").child("guestsOnTable").child("\(i)").removeValue()
                    }
                }
            }
        }
        
        self.guestList.remove(at: indexPath.row)

        self.guestsOnTableTableView.reloadData()
    }
}

enter image description here

【问题讨论】:

  • 什么错误信息???
  • @Sh_Khan 无法将“NSNull”(0x114b66dd0)类型的值转换为“NSArray”(0x114b66448)。 2021-04-05 15:32:20.045614+0200 我的婚礼 [8355:287880] 无法将“NSNull”(0x114b66dd0)类型的值转换为“NSArray”(0x114b66448)。 (lldb)
  • 您不能从实时数据库的数组中删除单个元素(当然可以,但不是您想的那样)。您将需要读入数组,对其进行修改,然后将其写回。阅读Arrays Are Evil

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


【解决方案1】:

您无法从实时数据库中的数组中删除单个元素(当然可以,但不是您想的那样)。

您需要读入、修改和写回数组。

实时数据库中的数组实际上是单个对象,而您通常在数组中看到的“索引”是固定数据。如果从 Firebase 中删除数组索引 2,它实际上就消失了,没有任何东西可以取代它,例如索引 2 将不再有任何价值 - 它将是 0、1、3...

一种解决方案是改变你的结构和代码。

guests
   userInfo
      uid_0 //someones uid
         tables
            guestsOnTable
               -Y8sjaoisjasdij89 //created with .childByAutoId - the firebaseKey
                  guest_name: "Kenny"
               -JY8hjoismosmooa
                  guest_name: "Dolly"

当填充 tableView 数据源时,从 Firebase 加载每个来宾并将其存储在类对象中

class GuestClass {
   var firebaseKey = ""
   var name = ""
}

并将这些对象存储在一个类级别的数组中,该数组将成为 tableView 的数据源

var guestArray = [GuestClass]()

最后,当用户删除第 1 行时,通过索引在数组中查找该对象

let myGuestToDelete = self.guestArray[rowNum] //rowNum = 1 in this case
let keyToRemove = myGuestToDelete.firebaseKey

然后基于该 firebase 密钥构建一个 firebase ref 以将其删除

let guestsRef = self.ref.child("guests") //self.ref points to my firebase    
let userIdRef = guestsRef.child("userInfo").child(the uid)
let refToRemove = child("tables").child("guestsOnTable").child(keyToDelete)
refToRemove.removeValue()
//and remove it from the array

还有一点需要注意;小心你的数据库嵌套的深度;深入的参考可能会导致问题发生。考虑将您的客人 onTable 拆分到更高级别的单独节点。

.childByAutoId 创建一个唯一的节点键

【讨论】:

  • 谢谢!我只有一个问题。因为我是 Swift 的新手,所以我不知道如何使用自己的 autoID 保存选定的行,这就是我使用数组的原因。您能解释一下如何使用自己的 ID 将所选行保存到 Firebase 吗?就像在你的例子中'guestsOnTable -Y8sjaoisjasdij89 //用.childByAutoId创建 - firebaseKey guest_name: "Kenny" -JY8hjoismosmooa guest_name: "Dolly" '
  • @BetYx 这是 Firebase 的一项功能,在实时数据库和 Firestore 中都提供。要使用 Firebase 生成的唯一密钥在 RTDB 中创建节点,请使用 .childByAutoId。例如,创建一个以Hello, World为值的节点; someRef.childByAutoId().setValue("Hello, World) - 将在 -Yuhi88789jska: Hello, World 的 someRef 中创建一个子节点,其中 -Yuhi88... 部分是“随机”节点键。入门指南 Updating or deleting data 对此进行了介绍
  • @BetYx 这里也有更全面的介绍Reading and writing lists
猜你喜欢
  • 2017-11-29
  • 1970-01-01
  • 1970-01-01
  • 2017-01-07
  • 2018-09-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-17
  • 2017-03-04
相关资源
最近更新 更多