Nicholas N Aliabadi Nicholas N Aliabadi - 10 months ago 91
iOS Question

Firebase: Closure in obvserveEventType and observeSingleEventOfType withBlock: Not executing (with assembly)

I cannot figure out why the databaseRef withBlock never executes.

I have already made a working real-time chat app in Swift & everything worked as expected so I'm not totally new at this...

The user logs in on a LoginViewController with Facebook auth and is forwarded to this main view. The tweets are stored in Firebase database.

When I set the breakpoints and step through this, it jumps down to the second error closure, repeats the error closure twice & then goes into the assembly instructions. (at bottom of post)

I've tried various ways of calling the observeEventType and observeSingleEventOfType (which is what I'd like to do) and the result is always the same here.

I've printed all the objects to console to make sure the user is logged in and with 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() {

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.homeTableView.insertRowsAtIndexPaths([NSIndexPath(forRow:0, inSection: 0)], withRowAnimation: UITableViewRowAnimation.Automatic)

}) {(error) in
}) {(error) in
print("Error 1") // never prints
print(error.localizedDescription) //never prints

I also noticed when stepping through the assembly instructions with xcode it gets to a cancel callback call.

This is where it starts (line 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

Then after several jumps it executes this instruction:

0x10f5b874e <+291>: movq 0x19ef03(%rip), %rsi ; "observeChildEventWithHandle:withCallbacks:cancelCallback:"

Answer Source

I really don't know what the problem seems this was an issue with Xcode.

I started a new project and copy n pasted my code from the malfunctioning one into the new one.

Once I had my first couple ViewControllers set up, everything worked fine.

Quite frustrating, especially since I don't know what caused the problem in the first place.

If I find anything out about what went wrong I'll update this post.

As you can see my code is nearly identical, but updated to Swift 3 syntax. It WAS working in 2.3 syntax originally...but I went ahead and updated everything to Swift 3.

class LoginViewController: UIViewController, FBSDKLoginButtonDelegate {

  @IBOutlet weak var uivLoadingSpinner: UIActivityIndicatorView!

  let loginButton: FBSDKLoginButton = FBSDKLoginButton()

  override func viewDidLoad() {

      let databaseRef = FIRDatabase.database().reference()

      self.loginButton.isHidden = true

      FIRAuth.auth()?.addStateDidChangeListener { auth, user in
          if let user = user {

              let userId = user.uid

              databaseRef.child("user_profile").child(userId).observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in

                      let handleDict = snapshot.value as! NSDictionary
                      let handle = handleDict.object(forKey: "handle") as! String

                      if(handle != "")
                          print("Has Handle = True")
                          self.performSegue(withIdentifier: "HomeViewSegue", sender: nil)
                          print("Has Handle = False")
                          self.performSegue(withIdentifier: "HandleViewSegue", sender: nil)
              // no user is signed in
              // show the login screen
              self.loginButton.readPermissions = ["public_profile", "email", "user_friends"]
              self.loginButton.delegate = self

              self.loginButton.isHidden = false