Как сохранить данные из асинхронного запроса Firebase в глобальной переменной? - PullRequest
0 голосов
/ 06 мая 2019

Я знаю, что об переполнении стека несколько раз спрашивали, но я не могу найти ответ, который ищу. Я пытаюсь сохранить данные из базы данных Firebase (с помощью метода наблюдающего единого (снимок)) в глобальной переменной. Подробнее см. Ниже код.

Я пытался добавить обработчик завершения и следовал инструкциям в Интернете, но при этом запроса наблюдаем единый перестал работать.

Что у меня было раньше:

class ItemsTableViewController: UITableViewController {

    let listToUsers = "ListToUsers"

    var user: User!
    let ref = Database.database().reference()

    override func viewDidLoad() {
        super.viewDidLoad()
        let defaultUser = User()
        ref.child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
            let value = snapshot.value as? NSDictionary
            defaultUser.uid = uid
            defaultUser.email = value?["email"] as? String ?? ""
            defaultUser.name = value?["name"] as? String ?? ""
            defaultUser.grad = value?["grad"] as? Int ?? 0
            defaultUser.number = value?["number"] as? String ?? ""
            defaultUser.image = UIImage(named: value?["image"] as? String ?? "")!
            completion(defaultUser)
        }) { (error) in
            print("hello")
            print(error.localizedDescription)
        }
        self.user = defaultUser
    }
}

То, что я пытался после и до сих пор не работает:

class ItemsTableViewController: UITableViewController {

    // MARK: Constants
    let listToUsers = "ListToUsers"

    // MARK: Properties
    var user: User!
    let ref = Database.database().reference()

    override func viewDidLoad() {
        super.viewDidLoad()
        let use = Auth.auth().currentUser?.uid
        self.getUserData(uid:use!) { (user) -> () in
            self.user = user
        }
}

func getUserData(uid:String , completion: @escaping (User) -> ()) {
        ref.child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
                let value = snapshot.value as? NSDictionary
                let defaultUser = User()
                defaultUser.uid = uid
                defaultUser.email = value?["email"] as? String ?? ""
                defaultUser.name = value?["name"] as? String ?? ""
                defaultUser.grad = value?["grad"] as? Int ?? 0
                defaultUser.number = value?["number"] as? String ?? ""
                defaultUser.image = UIImage(named: value?["image"] as? String ?? "")!
                completion(defaultUser)
        }){ (error) in
            print("hello")
            print(error.localizedDescription)
        }
    }

1 Ответ

0 голосов
/ 12 мая 2019

Firebase является асинхронным, и self.user = defaultUser в первом блоке кода будет вызываться еще до того, как Firebase сможет вернуть данные.

Данные действительны ТОЛЬКО в закрытии после вызова Firebase,Вот как это исправить.Да, и удалите этот код ошибки, так как он не нужен.

Предположим, что такая структура пользователя

users
  uid_0
    name: "some name"
    email: "some email"

и код для чтения в uid_0 и заполнение глобального (т. Е. Класса var) user

class MyUser {
    var uid = ""
    var name = ""
    var email = ""

    init(aUid: String, aName: String, aEmail: String) {
        self.uid = aUid
        self.name = aName
        self.email = aEmail
    }
}

var user: MyUser!

func readOneUser() {
    let uid = "uid_0"
    let thisUserRef = self.ref.child("users").child(uid)
    thisUserRef.observeSingleEvent(of: .value, with: { snapshot in
        //let uid = snapshot.key if you don't know the uid, it will be the key to the node
        let name = snapshot.childSnapshot(forPath: "name").value as? String ?? "No Name"
        let email = snapshot.childSnapshot(forPath: "email").value as? String ?? "No Email"
        self.user = MyUser(aUid: uid, aName: name, aEmail: email)
        print(self.user.name) //do something with the user here
    })
}

, и эту строку

defaultUser.image = UIImage(named: value?["image"] as? String ?? "")!

необходимо рассмотреть, но я не знаю, что это за намерение.Если это произойдет, это может привести к нулю

defaultUser.image = UIImage(named: "")!

, поэтому вы можете заполнить его каким-либо образом по умолчанию или обеспечить обработку ошибок, если оно равно нулю.

...