Я пытаюсь записать некоторые данные в базу данных 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)
}
Но я думаю использовать так:
Создайте частное перечисление для ваших эталонных ключей:
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 (или семафор), чтобы дождаться значения моментального снимка для продолжения:
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)
}
DispatchСемафор
@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")
}
Ой!! Я получил это, спасибо за вашу помощь :) Теперь мне интересно, есть ли способ заставить процесс, как я ожидал?
Привет @AlexChen, вы можете установить завершение своей функции, когда получено значение моментального снимка, вы можете вызвать завершение и установить свой autoId в завершении своей функции. Пожалуйста, отметьте как принять, если это работает. Наслаждаться!
Еще раз привет @AlexChen, пожалуйста, проверьте мое редактирование. Я надеюсь, что это полезно для вас.
Вы, наверное, знаете это, но для ясности, newPlanetRef.updateChildValues(autoId) недействителен; autoId var в этом случае представляет собой строку, а для updateChildValues требуется пара ключ: значение.
Firebase является асинхронным, и данные, возвращаемые из Firebase, действительны только в закрытии после функции. Прочитайте Блог Firebase по теме. Можете ли вы лучше объяснить, что вы пытаетесь сделать, поскольку представленный код неясен. Обратите внимание, что код работает быстрее, чем Интернет, поэтому любой код, следующий за вызовом firebase, будет выполнять до, данные возвращаются из Firebase.