#ios #swift #firebase #firebase-realtime-database #firebase-authentication
#iOS #swift #firebase #firebase-realtime-database #firebase-аутентификацией
Вопрос:
Я не могу понять, почему databaseRef withBlock никогда не выполняется.
Я уже создал рабочее приложение для чата в реальном времени в Swift, и все работало так, как ожидалось, поэтому я не совсем новичок в этом…
Пользователь входит в LoginViewController с помощью авторизации в Facebook и перенаправляется в это основное представление. Твиты хранятся в базе данных Firebase.
Когда я устанавливаю точки останова и выполняю это, он переходит ко второму закрытию ошибки, дважды повторяет закрытие ошибки и затем переходит к инструкциям по сборке. (внизу сообщения)
Я пробовал различные способы вызова observeEventType и observeSingleEventOfType (что я и хотел бы сделать), и результат здесь всегда один и тот же.
Я распечатал все объекты на консоль, чтобы убедиться, что пользователь вошел в систему и с FirebaseAuth .
import UIKit
import FirebaseAuth
import FirebaseDatabase
class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
{
var loggedInUser = FIRAuth.auth()?.currentUser
var loggedInUserDetails = AnyObject?()
@IBOutlet weak var homeTableView: UITableView!
var tweets = [AnyObject?]()
override func viewDidLoad() {
super.viewDidLoad()
let databaseRef = FIRDatabase.database().referenceWithPath("user_profile/(self.loggedInUser!.uid)")
print(self.loggedInUser!uid) // Prints uid
// get the logged in user -- POINT OF FAILURE
databaseRef.observeSingleEventOfType(.Value, withBlock: {(snapshot) in
//store the logged in user's details
self.loggedInUserDetails = snapshot
//get all the tweets by the user
databaseRef.child("tweets/(self.loggedInUser!.uid)").observeEventType(.ChildAdded, withBlock: {(snapshot:FIRDataSnapshot) in
self.tweets.append(snapshot)
self.homeTableView.insertRowsAtIndexPaths([NSIndexPath(forRow:0, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Automatic)
}) {(error) in
print(error.localizedDescription)
}
}) {(error) in
print("Error 1") // never prints
print(error.localizedDescription) //never prints
}
}
Я также заметил, что при выполнении инструкций по сборке с помощью xcode он переходит к отмене обратного вызова.
Здесь он начинается (строка 1)
0x10f5b3db8 < 36>: movq %r12, -0x30(%rbp)
0x10f5b3dbc < 40>: movq 0x1a7a8d(%rip), %rax ; (void *)0x000000010f762e70: FIRDatabaseReference
0x10f5b3dc3 < 47>: movq %rax, -0x28(%rbp)
0x10f5b3dc7 < 51>: movq 0x19f39a(%rip), %rsi ; "observeSingleEventOfType:withBlock:withCancelBlock:"
0x10f5b3dce < 58>: leaq -0x30(%rbp), %rdi
Затем после нескольких переходов он выполняет эту инструкцию:
0x10f5b874e < 291>: movq 0x19ef03(%rip), %rsi ; "observeChildEventWithHandle:withCallbacks:cancelCallback:"
Комментарии:
1. Если код переходит к одному из замыканий с ошибкой, у вас, скорее всего, нет разрешения на чтение данных.
error
Будет содержать информацию о точной ошибке (например, в каком месте вы пытаетесь прочитать, на которое у вас нет разрешения).2. Извините… Я забыл объяснить, что он никогда не выполняет код при закрытии ошибки. Я просто перехожу от ошибки к последней скобке, а затем возвращаюсь к ошибке. Есть ли другой способ найти ошибку? Я не видел никаких комментариев с ошибками в сборке.
3. Я проверил, чтобы подтвердить, что пользователь вошел в систему (в приведенном выше редактировании кода), и он распечатывает uid, как и ожидалось.
Ответ №1:
Возможно, вы получаете сообщение об ошибке.
// get the logged in user -- POINT OF FAILURE
databaseRef.observeSingleEventOfType(.Value, withBlock: {(snapshot) in
//store the logged in user's details
self.loggedInUserDetails = snapshot
//get all the tweets by the user
databaseRef.child("tweets/(self.loggedInUser!.uid)").observeEventType(.ChildAdded, withBlock: {(snapshot:FIRDataSnapshot) in
self.tweets.append(snapshot)
self.homeTableView.insertRowsAtIndexPaths([NSIndexPath(forRow:0, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Automatic)
}) {(error) in
print(error.localizedDescription)
}
}) {(error) in
print(error.localizedDescription) // maybe permission denied?
}
Комментарии:
1. Разве закрытие ошибки в конце не поймает это и не выведет его на консоль? При переходе через отладчик он проходит мимо последней скобки в withBlock
2. У вас есть вложенные наблюдатели, но вы обрабатываете только блок ошибок для внутреннего. Если
observeSingleEventOfType
наблюдение завершится неудачей, поскольку у вас нет блока ошибок, ничего не произойдет.3. Ах … не заметил этого, но ошибки нет. Это довольно неприятно… Я дополнил код мелким шрифтом comb…it похоже, что эта единственная вещь решила не сработать. Возможно, это какая-то причуда в xcode..
Ответ №2:
В конце концов, это была не проблема с Xcode…проблема заключалась в том, что TableView (numberOfRowsInSection) возвращал неправильное количество строк, и это все портило.
Я узнал, что Firebase не всегда выполняет действия в том порядке, в котором вы ожидаете.
Как только я обнаружил проблему, я прошел через отладчик, и он вошел в viewDidLoad, нажал observeSingleEvent, а затем перешел к концу закрытия….как я и думал, проблема. Но затем он перешел к моей функции TableView()-> UITableView и начал выполнение, прежде чем вернуться к observeSingleEvent, для которого мы пытаемся получить данные.
Почти кажется, что закрытие Firebase выполняется лениво.
Если я узнаю больше об этой теме, я исправлю этот ответ.
Приветствия!