ios - 持久化 Firebase 实时数据库在快照中创建空值

标签 ios swift firebase firebase-realtime-database

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

Database.database().isPersistenceEnabled = true

我没有更改任何内容,但突然它开始返回空快照。当我注释掉该行时,一切都再次正常工作,并且界面中的标签正确显示,并且该值在多个设备之间正确同步。这是我的 viewDidLoad 中的代码片段:

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 客户端会立即使用其已知的节点当前值触发。听起来在您的情况下,它认为该值为 null,因此它会随之触发。如果您有到服务器的连接,它将稍后使用从服务器获取的正确值触发。

处理这种情况的正常方法是首先check whether the snapshot exists ,在处理其内容之前。

关于ios - 持久化 Firebase 实时数据库在快照中创建空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58359892/

相关文章:

arrays - 如果数组是值类型并因此被复制,那么它们为什么不是线程安全的呢?

android - Firebase 数据库获取特定级别 android 的子项

ios - 地址簿和 map 套件

ios - 如何将 tableView 的多行传输到另一个 ViewController

swift - "__consuming"在 Swift 中有什么作用?

ios - 使 UICollectionViewFlowLayout 不在同一行上居中单元格

javascript - VueJS - 如何从方法内的函数更新组件数据?

android - Firebase .setCurrentScreen 用于基于 View 的应用

iPhone - SDK 中的 "Open In"?

ios - 可设计构建失败: Could not attach to pid : "26000"