1

Im currently using firebase to retrieve user info. once I receive the data I want to use the data outside of all closure the I create a completion block the problem is that I can not add the completion variable to the result because the result is inside another closure. How can fix this problem. Thank you in advance for the help.

 func userInfo(userId:String,completion:(result:String)->Void){


        fireBaseAPI().childRef("version_one/frontEnd/users/\(fireBaseAPI().currentUserId()!)/email").observeEventType(.Value, withBlock: {snapshot in

            let email = snapshot.value as! String

            //this is incorrect because it is inside a firebase closure how can I make it work I know i have it outside the closure but i will not be able to retrieve the info from firebase
            result = email

        })




    }
SwiftER
  • 1,235
  • 4
  • 17
  • 40

2 Answers2

3

As far as i could understand your problem ::---

You want to send the emailID of your user in the completionBlock: once retrieved, But i still don't have any idea to what fireBaseAPI() is :-

func userInfo(userId:String,completion:((result:String)->Void){
fireBaseAPI().childRef("version_one/frontEnd/users/\(fireBaseAPI().currentUserId()!)/email").observeEventType(.Value, withBlock: {snapshot in

        let email = snapshot.value as! String
        completion(result:email)
    })
}
Dravidian
  • 9,945
  • 3
  • 34
  • 74
1

You could create a variable in your class (outside of the closure) and then store the snapshot.value result in that variable like this:

EDIT

var emailResult: String?

func getUserEmail {
    fireBaseAPI().child("version_one/frontEnd/users/\(fireBaseAPI().currentUserId()!)/email").observeEventType(.Value, withBlock: {snapshot in
        let email = snapshot.value as! String
        self.emailResult = email
    })
}
alexisSchreier
  • 677
  • 1
  • 5
  • 21
  • that result will always come back nil because the the variable is set it is inside of the closure that is the reason i had to make a completion handler – SwiftER Sep 03 '16 at 20:37
  • I just edited my answer. I don't know what the rest of your class looks like but could you do something like what I wrote above? Why do you need to pass in `userId:String` in your original `userInfo` method since you're calling `fireBaseAPI().currentUserId()` to get the user ID? And why do you need to add a completion handler on top of the Firebase closure `withBlock`? – alexisSchreier Sep 03 '16 at 20:57
  • 2
    Hey iOSMoonSand. This will indeed ensure that the email result is available outside of `getUserEmail()`. Firebase loads the data asynchronously, so the callback may be invoked (much) later. Even "worse": Firebase will continue to synchronize the data, so the email result may change over time. The main problem with your code is to know **when** email result is available and (even more difficult) when it is updated. That's why Dravidian's approach with a callback (while initially less intuitive) is more idiomatic for these calls. – Frank van Puffelen Sep 04 '16 at 03:35