2017-05-08 31 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)