-1
func observeActiveTrackingState() -> String{

    let pathToObserveState = databaseRef.child("locationState").child("\(userID!)")

    pathToObserveState.observeSingleEvent(of: .value, with: { (snapshot) in

        let snapshotValue = snapshot.value as? NSDictionary

        print("Snapshot Returned (ObserveActiveTrackingState) = \(snapshotValue?["state"] as! String)")

        let currentState = snapshotValue?["state"] as! String

        return currentState //*****GIVES ME AN ERROR*****

        })
    //IF I PUT THE RETURN HERE HOW DO I CALL THE CURRENTSTATE VARIABLE
}

I have a function called "observeActiveTrackingState" that is supposed to return a string and typically when add a return it returns the string variable that I want however since I need to put the return statement under

pathToObserveState.observeSingleEvent(of: .value, with: { (snapshot) in


    }) 

It returns an error and says it needs to happen outside of firebase's completion block. How do I fix this code so that when I call the function I get the variable that I want

AL.
  • 36,815
  • 10
  • 142
  • 281
BrandonMayU
  • 726
  • 2
  • 6
  • 13
  • 2
    Possible duplicate of [Returning data from async call in Swift function](http://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function) – Fogmeister Apr 11 '17 at 20:55
  • You cannot do this like this at all. You are trying to return from a synchronous method using the result of an async method. It doesn't work. – Fogmeister Apr 11 '17 at 20:55
  • @Fogmeister what is a way I can work around this? – BrandonMayU Apr 11 '17 at 21:07
  • This has been asked and answered many times on stack overflow. That's why I marked it as a duplicate. Google the problem. You will get an answer. – Fogmeister Apr 11 '17 at 21:08
  • This isn't how Firebase works. You (generally) will want to work with the data returned in the snapshot within the closure, which is the only time it's valid. Avoid adding callbacks and other completion handlers as it can create other issues. See my answer to [This question](http://stackoverflow.com/questions/40703318/cant-find-in-stack-work-answer-on-how-to-know-when-firebase-retrieved-data/40704993#40704993) as it may provide some insight. – Jay Apr 12 '17 at 18:11

1 Answers1

0

you should use a closure that accepts a parameter of the type that you want to return:

func observeActiveTrackingState(_ completion: (String) -> ()) {

    let pathToObserveState = databaseRef.child("locationState").child("\(userID!)")

    pathToObserveState.observeSingleEvent(of: .value, with: { (snapshot) in

        let snapshotValue = snapshot.value as? NSDictionary

        print("Snapshot Returned (ObserveActiveTrackingState) = \(snapshotValue?["state"] as! String)")

        let currentState = snapshotValue?["state"] as! String

        completion(currentState)

    })
}

//

you can create a global closure variable and call it:

    let state: (String) -> ()

    func observeActiveTrackingState() {

        let pathToObserveState = databaseRef.child("locationState").child("\(userID!)")

        pathToObserveState.observeSingleEvent(of: .value, with: { (snapshot) in

            let snapshotValue = snapshot.value as? NSDictionary

            print("Snapshot Returned (ObserveActiveTrackingState) = \(snapshotValue?["state"] as! String)")

            let currentState = snapshotValue?["state"] as! String

            self.state(currentState)

        })
    }
nsleche
  • 108
  • 1
  • 7
  • So far it seems to be working however how do I call this in the code for example I want to be able to in the "viewDidLoad" set a variable to this function. " let ActiveState = observeActiveTrackingState() " – BrandonMayU Apr 12 '17 at 02:44
  • when I do this I get an error saying there are no initializers – BrandonMayU Apr 12 '17 at 06:05
  • @BrandonMayU these are all problems that have been answered many many times before. You would do well to read the Swift book that is available for free from Apple. – Fogmeister Apr 12 '17 at 08:27