【问题标题】:How to write nil value in Firebase in Swift?如何在 Swift 的 Firebase 中写入 nil 值?
【发布时间】:2017-12-15 11:47:15
【问题描述】:

我有一个 struct 持有不同类型的数据,我想将其写入 Firebase。我的结构的某些属性可以为零,因此它们应该写入数据库。

写入 Firebase 时如何处理 nil 值?

 struct Booking{

  let bookingNumber:String
  let bookingCompleted:Bool
  let cancelledBy:[String:AnyObject]?

       init(bookingNumber:String,
          bookingCompleted:String){
         self.bookingNumber = bookingNumber
         self.bookingCompleted = bookingCompleted
        }

      init(cancelledBy:[String:AnyObject]){
           self.cancelledBy = cancelledBy
        }
}

class DisbursePayment {

   override func viewDidLoad() {
    super.viewDidLoad()
   //how to handle if cancelledBy is nil? It will throw error :  unexpectedly 
   //found nil while unwrapping an Optional value
   //How should I structure my data in `struct Booking`?
   let item = Booking(cancelledBy: valueCouldBeNil)  
  }
}

【问题讨论】:

  • 首先摆脱所有那些隐式展开的选项。它们不能为 nil,只是将它们设为非可选,否则将它们声明为常规可选 ?
  • @LeoDabus 如果我摆脱了可选项,那么在初始化程序中,编译器会抱怨“从初始化程序返回而不存储所有存储的属性”
  • 就像我说的那些可以为 nil 的声明它们为常规可选
  • Btw Swift 本机字典类型,因为 Swift 3 是 [String:Any]
  • 关于属性命名的旁注:bookingNumber 是多余的,您应该将其命名为 number。同样适用于bookingCompleted,只需将其更改为completed

标签: swift firebase


【解决方案1】:

从cmets看来你已经想出了一个解决方案,我想补充以下信息以供其他人参考:

如果不需要某个值,则不应将 nil 值存储在 firebase(或任何数据库中,因为它会破坏 1NF 重复值),如果存在,则仅应将其设置为数据库。否则将其初始化为 nil 并使用可选链安全地解开该值(如果存在)。

考虑以下将其非必需属性“title”初始化为 nil 的对象

Class CustomObject: NSObject {
     //…
     var title: String? = nil
     //…
}

设置

在firebase中设置值时,如果存在,我们可以使用可选链来设置值,否则,不要将其添加到要保存到firebase中子对象引用的值中,如果存在则删除当前值。

   //Create a new reference to Firebase Database
   var ref: DatabaseReference!
   ref = Database.database().reference().child(<#your child id#>)

    //Make a Dictionary of values to set
    var values:[String:Any] = [:]

    //Set required values like uuid or other primary key

    //Use Optional Chaining to set the value
    //Note that if title is nil 
    //it doesn’t override any existing value in firebase for title i.e. the old value will still remain.
    if let title = myObject.title {
            values["title"] = title
          } else {
            //if the value was previously set but now is not, 
            //we should update firebase by removing the value.
            ref.child("title").removeValue()
         }

    //…

    //Finally, push the remaining values to firebase to up date the child
    ref.updateChildValues(values)

获取

为了从firebase获取值,我们再次使用可选链来查看给定键的值是否存在,这里我通过其子路径访问对象,您的查询可能不同但概念相同。

    //Create a new reference to Firebase Database
    var ref: DatabaseReference!
    ref = Database.database().reference().child(<# child path #>)
    ref.queryOrderedByValue().observeSingleEvent(of: .value) { (snapshot) in
            if (snapshot.value is NSNull) {
                print("No Items to Fetch")
            } else  {
                //enumerate over the Objects
                for child in snapshot.children.allObjects as! [DataSnapshot] {
                    if let object = child.value as? [String : AnyObject] {

                           let myObject = CustomObject()

                            if let title = object["title"] as? String {
                                   myObject.title = title
                              }
                               //If There is no value for 'title' it will not be set.
                               //…


//Then use the value as you normally would…
if (myObject.title != nil) {//..}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-04
    • 2018-08-14
    相关资源
    最近更新 更多