2017-12-19 34 views
0

タイトルにFirebaseから単純なデータを取得するのに奇妙な問題があると言われていますが、どこに間違っているのか分かりません。Swiftを使用してFirebaseからデータを取得できません

これは私のスキーマです:

enter image description here

そして、このコード:

import Firebase 

let DB_BASE = Database.database().reference() 

class FirebaseService { 

    static let instance = FirebaseService() 

    private var REF_BASE = DB_BASE 
    private var REF_SERVICE_STATUS = DB_BASE.child("Service_Status") 

    struct ServiceStatus { 
     var downloadStatus: Bool 
     var uploadStatus: Bool 
    } 

    func getServiceStatus() -> (ServiceStatus?) { 
     var serviceStatus: ServiceStatus? 

     REF_SERVICE_STATUS.observeSingleEvent(of: .value) { (requestSnapshot) in 

      if let unwrapped = requestSnapshot.children.allObjects as? [DataSnapshot] { 
       for status in unwrapped { 
        serviceStatus.downloadStatus = status.childSnapshot(forPath: "Download_Status").value as! Bool 
        serviceStatus.uploadStatus = status.childSnapshot(forPath: "Upload_Status").value as! Bool 
       } 
       // THANKS TO JAY FOR CORRECTION 
       return sponsorStatus 
      } 
     } 
    } 
} 

が、最後にserviceStatusはnilです。何かアドバイス?

+0

このリンクをチェックアウト*リターン*が適切に使用されていない選択肢が常にあります。この場合、Firebase関数のコードがサーバーからデータを返す前に、リターンが実行されます。 Firebaseは非同期なので、そのようにコード化する必要があります。 [ダウンロード後の動作](https://stackoverflow.com/questions/43027817/how-to-perform-an-action-only-after-data-are-download-from-firebase/43029121#43029121)と[Firebase async task](https://stackoverflow.com/questions/38550634/swift-firebase-return-in-asynchron-task/38551937#38551937) – Jay

+0

@Jayありがとう、私はそれを修正しましたが、問題はserviveStatusが実際にはnil !データを取得するのに間違ったことをしていますか? – user3582537

答えて

0

私はあなたのコードをより管理しやすくするために単純化することができると思います。試してみてください

let ssRef = DB_BASE.child("Service_Status") 
ssRef.observeSingleEvent(of: .value) { snapshot in 
    let dict = snapshot.value as! [String: Any] 
    let down = dict["Download_Status"] ?? false 
    let up = dict["Upload_Status"] ?? false 
} 

??ノードがnil(つまり存在しない場合)のデフォルト値falseを返します。

ああ、Firebase非同期呼び出し(クロージャ)からデータを返そうとすると、実際には動作しません(そのまま)。

通常の関数はコードを同期して伝播し、呼び出し元関数に値を返すので、呼び出し関数は次のコード行に進みます。

Firebase関数を呼び出すとすぐに、コードはの前にうまくいくでしょう。の前に、Firebaseはサーバからデータを取得し、戻り値varを設定します。つまり、しないでください。

ので

Run code only after asynchronous function finishes executing

関連する問題