【问题标题】:Persisting Firebase Realtime Database creates null value in snapshot持久化 Firebase 实时数据库在快照中创建空值
【发布时间】:2020-02-10 01:57:37
【问题描述】:

所以我的应用程序运行良好;我使用以下方法在本地持久化数据库:

Database.database().isPersistenceEnabled = true

我什么都没做,但突然间它开始返回一个空快照。当我注释掉该行时,一切正常,界面中的标签显示正确,并且该值在多个设备之间正确同步。这是我的 viewDidLoad 中的代码 sn-p:

import UIKit
import Firebase
import FirebaseDatabase

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var returnedName: UILabel!
    @IBOutlet weak var scannedURLTextField: UITextField!
    @IBOutlet weak var reentries: UILabel!
    @IBOutlet weak var visitors: UILabel!
    @IBOutlet weak var ticketType: UILabel!
    @IBOutlet weak var statusImage: UIImageView!
    @IBOutlet weak var entryOrReentrySwitch: UISwitch!


    var qrDecodedURL : String!
    var ticketNumber : String!
    var eventID : String!
    var numberOfAttendees: String!
    var urlDictionary = [String : Any]()
    var attendeeRef: DatabaseReference!
    var ticketRef : DatabaseReference!
    var entries : DatabaseReference!
    var entriesRef : DatabaseReference!
    var reentriesRef : DatabaseReference!
    var entriesInt : Int!
    var reentriesInt : Int!


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        Database.database().isPersistenceEnabled = true

        attendeeRef = Database.database().reference(withPath: "attendees")
        ticketRef = Database.database().reference(withPath: "tickets")

        entriesRef = Database.database().reference(withPath: "entries")

        reentriesRef = Database.database().reference(withPath: "reentries")

        self.scannedURLTextField .becomeFirstResponder()
        scannedURLTextField.inputView=UIView()//create dummy view to supress keyboard

        //        Incresase size of switch
        entryOrReentrySwitch.transform = CGAffineTransform(scaleX: 1.5, y: 1.5);

        //monitor for changes in entries
        entriesRef.child("entries").observe(.value, with: { (snapshot) in
            print(snapshot);
            self.visitors.text = "Visitors: \(snapshot.value as! String)"
            let tempValue = snapshot.value as! String
            self.entriesInt = Int(tempValue)
        })


        //Monitor for changes in reentries
        reentriesRef.child("reentries").observe(.value, with: { (snapshot) in
            //            print(snapshot);
            self.reentries.text = "Reentries: \(snapshot.value as! String)"
        })

        statusImage.image = UIImage.init(named: "scanQR.png")
    }

产生的错误是:

Could not cast value of type 'NSNull' (0x1fb2f3270) to 'NSString' (0x1fb2fcab8).
2019-10-12 18:05:54.061687-0700 VIM Tickets[621:97014] Could not cast value of type 'NSNull' (0x1fb2f3270) to 'NSString' (0x1fb2fcab8).

它在监视器中的 self.visitors.text = "Visitors: \(snapshot.value as! String)" 上失败,以检查条目部分的变化。同样,一切正常,当我注释掉数据库持久性行时,快照中有数据。我什至将它移到了 AppDelegate,但结果相同。

我有点不知所措,为什么会在之前持久性起作用时发生这种情况。任何建议将不胜感激!

【问题讨论】:

  • 我还升级到了最新版本的 Firebase SDK(注意:如果您最近升级到 macOS Catalina,您可能需要重新安装 Cocoapds(sudo gem install cocoapods),然后再进行 pod 更新),但这也无济于事。

标签: ios swift firebase firebase-realtime-database


【解决方案1】:

启用磁盘持久性后,Firebase 客户端会立即使用它知道的节点当前值触发。听起来在你的情况下它认为值是null,所以它会触发它。如果您与服务器建立了连接,它会在稍后以从服务器获得的正确值触发。

处理这种情况的正常方法是先check whether the snapshot exists,然后再处理其内容。

【讨论】:

  • 感谢您的建议。我不确定如何解决这个问题,因为 Firebase 要求 Database.database().isPersistenceEnabled = true 必须是任何其他数据库操作之前的第一条语句。如果在检索快照或设置引用后放置它,则会出现错误:“必须在 FIRDatabase 实例的任何其他使用之前调用 setPersistenceEnabled。”请您的解释更明确一点吗?
  • 在您的.observe(.value, 的完成处理程序中,首先检查if snapshot.exists(),然后再处理其内容。
猜你喜欢
  • 1970-01-01
  • 2021-03-26
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 2019-05-07
  • 2021-01-21
  • 1970-01-01
  • 2017-03-27
相关资源
最近更新 更多