无法将类型'__NSDictionaryM'(0x1111152b0)的值强制转换为'FIRDataSnapshot'Firebase Swift 3

无法将类型'__NSDictionaryM'(0x1111152b0)的值强制转换为'FIRDataSnapshot'Firebase Swift 3

问题描述:

我正在尝试从Firebase数据库读取嵌套的数据结构,但是当[String:AnyObject]类型的对象可能为nil时,我不知道如何处理这种情况.
调用readFeesCleaner(callback_)时,将引发错误.

I am trying to read nested data structures from Firebase Database, but I don't know how to manage the case when an object of type [String:AnyObject] could be nil.
When readFeesCleaner(callback_) is called, it throws an error.

  func readFeesCleaner(callback: @escaping ((_ feesCleaner: FeesCleaner) -> Void)) {

 dbRef.child("FeesCleaner").child(self.uidOfTextField!).observeSingleEvent(of: .value, with: { (snapshot: FIRDataSnapshot) in

        guard !(snapshot.value is NSNull) else {
            return
        }

       //throws error: signal SIGABRTCould not cast value of type '__NSDictionaryM' (0x1111152b0) to 'FIRDataSnapshot' (0x10ef16d18).
            let feesCleanersReceived = FeesCleaner(snapshot: (snapshot.value)! as! FIRDataSnapshot)
                callback(feesCleanersReceived)

    }) { (error:Error) in
        print(#line, "\(error.localizedDescription)")
    }
 } 


struct FeesCleaner {

   var outstandingFees: AnyObject!
   var timeStampFeesSaved: [String:AnyObject]!
   var backgroundCheck: AnyObject!

    init(
       outstandingFees: AnyObject? = nil, //value might not exist when reading
       timeStampFeesSaved: [String:AnyObject]? = nil,// value might not exist when reading
       backgroundCheck: AnyObject) {

       self.outstandingFees = outstandingFees
       self.timeStampFeesSaved = timeStampFeesSaved
       self.backgroundCheck = backgroundCheck   
  }//end of init

    //read data here
     [full struct data here][1]
      https://gist.github.com/bibscy/dc48f7107459379e045a50fdbbc35335


}//end of struct

这里有很多问题.首先:

There's a number of issues here. First:

如何处理类型为[String:AnyObject]的对象的情况 可能是零.

how to manage the case when an object of type [String:AnyObject] could be nil.

您已使用上一条语句处理了此问题,请注意,您也可以添加

You've handled that with the prior statement, noting that you can also add

if snapshot.exists == false {return}

第二个:您必须正确处理可选选项-如果var可能为nil,则需要适当的代码来处理这种情况,而不是对其进行耕作.如果您强行打开可选包装,则实际上是在肯定地说,它永远不会为零,因此从根本上讲,不要这样做.

Second: You've got to handle optionals properly - if a var could be nil, you need code in place to handle that situation and not plow through it. If you force unwrap an optional you are essentially stating that for sure, it will never be nil, so basically, don't do that.

一种解决方法是简单地将快照作为DataSnapshot传递,然后一次取出一个属性.如果存在,则将其分配(如果未设置为0或nil或其他占位符).

One fix could be to simply pass the snapshot as a DataSnapshot and then pull out the properties one at a time; if they exist, assign them, if not set to 0 or nil or some other placeholder.

Firebase封闭中的内容如下:

Something like this inside the Firebase closure:

let feesCleanersReceived = FeesCleaner(withSnapshot: snapshot)

然后是这样的结构:请注意,我们正在利用nil合并运算符??

and then your struct like this: note we are leveraging the nil coalescing operator, ??

struct FeesCleanerStruct {
    var outstandingFees: String?
    var timeStampFeesSaved: String?

    init(withSnapshot: DataSnapshot) {
        let dict = withSnapshot.value as! [String: Any]
        self.outstandingFees = dict["outstandingFees"] as? String ?? "0.0"
        self.timeStampFeesSaved = dict["timeStampFeesSaved"] as? String ?? "0"
    }
}