swift - 从 firebase 数据库查询数据时的奇怪行为

标签 swift firebase firebase-realtime-database

我试图在 firebase 数据库中写入一些数据,但是我得到了错误的运行过程。有人可以帮我吗?非常感谢!!

JSON树结构如下:

{ 
    "cars": {

        "auto id": [

            "parts": "wheel"
             ...
    .
    .
    .



@objc func buttonTapped(){

    print("before running")
        var ref = Database.database().reference(withPath: "cars").queryOrdered(byChild: "parts").queryEqual(toValue: "wheel")
            ref.observeSingleEvent(of: .childAdded, with: { (snapshot) in
            autoId = snapshot.key
            print("running")
        }) { (error) in
            print(error.localizedDescription)
        }
print("after running")
let newPlanetRef = Database.database().reference().child("company").childByAutoId()
                    newPlanetRef.updateChildValues(autoId)
}

我期望运行的进程是

"before running"->"running"->"after running"

但实际过程是

"before running"->"after running"->"running" And the data cannot be updated to database unless I put the update function inside the closure

最佳答案

这是一个异步过程。

你应该这样使用:

var newPlanetRef: String? //It should be your reference type

var ref = Database.database().reference(withPath: "cars").queryOrdered(byChild: "parts").queryEqual(toValue: "wheel")
        ref.observeSingleEvent(of: .childAdded, with: { (snapshot) in
        autoId = snapshot.key
        newPlanetRef = Database.database().reference().child("company").childByAutoId()
        newPlanetRef.updateChildValues(autoId)
        print("running")
    }) { (error) in
        print(error.localizedDescription)
    }

但我认为这样使用:

  • 为您的引用 key 创建私有(private)枚举:

    private enum ReferenceKeys {
        static let carsKey = "cars"
    }
    
  • 创建数据库引用的全局变量:

    var database = Database.database()
    var databaseReference = database.reference()
    var carReference = database.reference(withPath: ReferencesKeys.carsKey)
    
  • 像这样使用您的函数:

    var newPlanetRef: String?
    
    var reference = carReference.queryOrdered(byChild: "parts").queryEqual(toValue: "wheel")
    
    reference.observeSingleEvent(of: .childAdded, with: { [weak self] snapshot in
    
        self?.autoId = snapshot.key
        newPlanetRef = databaseReference.child("company").childByAutoId()
        newPlanetRef.updateChildValues(autoId)
    
        print("running")
    }) { error in 
    
        print(error.localizedDescription)
    }
    

奖励:

您可以使用 dispatchGroup(或信号量)等待快照值以进行:

调度组

@objc func buttonTapped(){

    let dispatchGroup = DispatchGroup()

    print("before running")
    var ref = Database.database().reference(withPath: "cars").queryOrdered(byChild: "parts").queryEqual(toValue: "wheel")

    dispatchGroup.enter()
    ref.observeSingleEvent(of: .childAdded, with: { [weak self]snapshot in
            self?.autoId = snapshot.key

            dispatchGroup.leave()
            print("running")
    }) { (error) in
            print(error.localizedDescription)
    }
    print("after running")
    let newPlanetRef = Database.database().reference().child("company").childByAutoId()
    newPlanetRef.updateChildValues(autoId)
}

调度信号量

@objc func buttonTapped(){

    let dispatchSemaphore = DispatchSemaphore(value: 1)

    print("before running")
    var ref = Database.database().reference(withPath: "cars").queryOrdered(byChild: "parts").queryEqual(toValue: "wheel")

    ref.observeSingleEvent(of: .childAdded, with: { [weak self]snapshot in
            self?.autoId = snapshot.key
            semaphore.signal()

            print("running")
    }) { (error) in
            print(error.localizedDescription)
    }

    semaphore.wait()

    print("after running")
    let newPlanetRef = Database.database().reference().child("company").childByAutoId()
    newPlanetRef.updateChildValues(autoId)
}

完成

@objc func buttonTapped(){

    getData { [weak self] snapshotKey in
        self?.autoId = snapshot.key
        let newPlanetRef = Database.database().reference().child("company").childByAutoId()
        newPlanetRef.updateChildValues(self?.autoId)
    }
}

/// completion type -(String?)- must be a snapshot.key's type
func getData(_ completion: @escaping (String?) -> Void) {

    print("before running")
    var ref = Database.database().reference(withPath: "cars").queryOrdered(byChild: "parts").queryEqual(toValue: "wheel")

    ref.observeSingleEvent(of: .childAdded, with: { snapshot in
            completion?(snapshot.key)

            print("running")
    }) { (error) in
            print(error.localizedDescription)
    }

    print("after running")

}

关于swift - 从 firebase 数据库查询数据时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56898986/

相关文章:

ios - 图像在 TableView 的数据搜索结果中表现不准确

ios - Firebase 3x 方法不适用于真实设备但适用于模拟器 Swift 3.0

ios - AVMutableComposition 的性能问题 - scaleTimeRange

swift - 使用 Finder 打开下载目录,必要时提示用户许可

swift - @AppStorage 不更新 View

android - 无法使用 Flutter 将文件上传到 FirebaseStorage

ios - 解析 iOS 9 的 FacebookUtils 失败并出现 -canOpenURL 错误

javascript - 10 小时后删除 Firebase 子级

java - 如何将数组转换为列表而不是 Firebase?

java - Firebase 数据库 - "Fan Out"技术