2017-05-08 32 views
0

我做了一个连接到firebase的函数,转到特定路径,然后给我值。当我打印(snapshot.value)时,它给了我我需要的价值。当我调用该函数时,userProfile为空。我需要userProfile来返回快照String。返回声明在Swift中使用Firebase时出错

func getUserData(uid: String) -> String{ 
    var _REF_USERNAME = FIRDatabase.database().reference().child("users").child(uid).child("profile").child("username") 

    var userProfile = String() 


    _REF_USERNAME.observe(.value, with: {(snapshot) in 
     print("SNAP: \(snapshot.value)") 
      userProfile = snapshot.value as! String 

    }) 
    print(userProfile) 
    return userProfile 
} 
+1

从Firebase返回数据之前执行返回。 Firebase数据在闭包内成为* only *有效。请参阅我的答案[这个问题](http://stackoverflow.com/questions/43823808/access-firebase-variable-outside-closure/43832208#43832208),也[这一个](http://stackoverflow.com /问题/ 43130730 /表视图-IS-未显示最评论或 - 用户名 - 从-火力/ 43157576#43157576)。您通常不应尝试从Firebase函数返回数据,因为它是异步的,其余代码是同步的。 – Jay

回答

2

斯威夫特3

要调用USERPROFILE回调外观察,所以前的观察功能,它会被执行异步完成。回调起初很难理解,但总体思路是你的代码不是从上到下按顺序运行的,并且有一部分代码是在后台线程中异步运行的。

要访问USERPROFILE,你有一个回调函数就这样传递:

func observeUserProfile(completed: @escaping (_ userProfile: String?) ->()) -> (FIRDatabaseReference, FIRDatabaseHandle) { 

    let ref = _REF_USERNAME 

    let handle = ref.observe(.value, with: {(snapshot) in 
      if !snapshot.exists() { // First check if userProfile exists to be safe 
       completed(nil) 
       return 
      } 
      userProfile = snapshot.value as! String 
      // Return userProfile here in the callback 
      completed(userProfile) 
    }) 
    // Good practice to return ref and handle to remove the handle later and save memory 
    return ref, handle 

而且你把这种外监视代码,同时通过在回调函数那样:

let ref, handle = observeUserProfile(completed: { (userProfile) in 
    // Get access to userProfile here 
    userProfile 
} 

而当你与这个观察者做,从观察这样做节省内存以下停止:

ref.removeObserver(withHandle: handle)