2016-11-29 17 views
1

私は電子メールとパスワードで入力する際に​​部門の構造を持っていますが、電子メールで部門のモデルを探していますが、エラーが発生しました。たとえば、最初のアプローチでは、クエリがモデルを返し、次のクエリでNSNullを返すことができます。Firebaseは同じクエリに対して異なる結果を返します。 iOS

部門のデータ構造。

{ 
    "departments" : { 
    "19537648-B6DA-4F63-9AFF-EFC4754630D6" : { 
     "createdAt" : "502100506.440385", 
     "email" : "[email protected]", 
     "isCertified" : false, 
     "isMain" : false, 
     "mainVendorID" : "YeLf8kzE1LfWwHnWwLJTWsaPinI3", 
     "title" : "", 
     "uid" : "19537648-B6DA-4F63-9AFF-EFC4754630D6" 
    }, 
    "4552E741-B9B6-4733-84C1-7DE7FFC0FD4B" : { 
     "createdAt" : "502100536.218835", 
     "email" : "[email protected]", 
     "isCertified" : false, 
     "isMain" : false, 
     "mainVendorID" : "YeLf8kzE1LfWwHnWwLJTWsaPinI3", 
     "title" : "", 
     "uid" : "4552E741-B9B6-4733-84C1-7DE7FFC0FD4B" 
    }, 
    "DBEFBF16-71FE-4AB6-BEA6-5BF042D1AB1D" : { 
     "createdAt" : "502100521.083035", 
     "email" : "[email protected]", 
     "isCertified" : false, 
     "isMain" : false, 
     "mainVendorID" : "YeLf8kzE1LfWwHnWwLJTWsaPinI3", 
     "title" : "", 
     "uid" : "DBEFBF16-71FE-4AB6-BEA6-5BF042D1AB1D" 
    } 
    } 

何が問題とどのようにそれを修正することができ

let ref = FIRDatabase.database().reference() 
      .child(FirebaseDatabaseManager.DatabaseMainGateways.departments.rawValue) 
      .queryOrdered(byChild: "email").queryEqual(toValue: departmentEmail) 

ref.observeSingleEvent(of: .value, with: { (snapshot) in 
    if snapshot.value is NSNull { 
     debugPrint(“value is NSNull”) 
     notExist?() 
    } else { 

    } 
}, withCancel: { (error) in 

}) 

私の要求?ありがとう!

UPDATE

Firebaseルール

{ 
    "rules": { 
    ".read": true, 
    ".write": "auth != null", 

    "departments": { 
     ".indexOn": "email" 
    }, 

    } 
} 

UPDATE 1

タスク次に、我々がメインベンダーに行くときことを確認する必要があった(通常Firebaseユーザー自分の部門(データに特別な制限があるユーザー)を作成するために、ユーザーにGoogleプラスまたは電子メールを使用してログインすることができます。すでにアカウントを持っていれば、Firebaseはシステムに新しいユーザを登録することはできませんが、メインベンダーが自分の部門にユーザ名とパスワードを渡す必要があります。だから私は違ったやり方をした。新しい部門を作成するとき(電子メールで)、まず、メインベンダーのリストにある別の部門の作成時にすでに電子メールが追加されているかどうかをチェックします。部門は、このメールによって作成されていない場合

func addDepartment(departmentModel: RealmVendor, success: (() -> Void)?, isCreated: (() ->())?, fail: ((_ error: Error) ->())?) { 
    guard let currentVendor = RealmManager.shared.getCurrentVendor(isMain: true) else { return } 

    let checkingQuery = FIRDatabase.database().reference().child(FirebaseDatabaseManager.DatabaseMainGateways.vendors.rawValue).child(currentVendor.uid).child(DatabaseMainVendorGateways.departmentsEmails.rawValue).queryEqual(toValue: departmentModel.email).queryOrderedByValue() 

    queries.append(checkingQuery) 

    checkingQuery.observeSingleEvent(of: .value, with: { (snapshot) in 
     if snapshot.value is NSNull { 
      // creating a new department 
      debugPrint("Create a new department") 
      self.createDepartment(departmentModel: departmentModel, success: { 
       success?() 
      }, fail: { (error) in 
       fail?(error) 
      }) 
     } else { 
      // department was created 
      debugPrint("department was created") 
      isCreated?() 
     } 
    }) { (error) in 
     debugPrint("error", error) 
     fail?(error) 
    } 
} 

次のステップは、その後、私は、メインベンダー

private func createDepartment(departmentModel: RealmVendor, success: (() -> Void)?, fail: ((_ error: Error) ->())?) { 
    guard let currentVendor = RealmManager.shared.getCurrentVendor(isMain: true) else { return } 
    let ref = FIRDatabase.database().reference().child(FirebaseDatabaseManager.DatabaseMainGateways.vendors.rawValue).child(currentVendor.uid).child("departmentsEmails").childByAutoId() 
    ref.keepSynced(true) 

    references.append(ref) 

    ref.setValue(departmentModel.email) { (error, ref) in 
     if error == nil { 
      // save department to realm that we can show all departments in department list in app 
      debugPrint("save department to realm", departmentModel.uid) 

      RealmManager.shared.saveVendor(departmentModel) 

      self.createFirstDepartmentModel(departmetnModel: departmentModel) 
      success?() 
     } else { 
      fail?(error!) 
     } 
    } 
} 

のモデルのリストに電子メールを追加それから私は、作成する関数を呼び出します部門の最初のモデル。

private func createFirstDepartmentModel(departmentModel: RealmVendor) { 
    FirebaseDatabaseDepartmentManager.shared.savePreservationDepartmentOnServer(departmentModel) 
} 


func savePreservationDepartmentOnServer(_ realmDepartment: RealmVendor) { 
    let refDatabase = FIRDatabase.database().reference().child(FirebaseDatabaseManager.DatabaseMainGateways.vendorDepartments.rawValue).child(realmDepartment.mainVendorUID!).child(realmDepartment.uid) 

    references.append(refDatabase) 

    refDatabase.observeSingleEvent(of: .value, with: { (snapshot) in 
     if let _ = snapshot.value as? [String : Any] { 
      // already existed. save the updated model, since the seller has already registered with the server, and not to spoil its current data 
     } else { 
      refDatabase.keepSynced(true) 
      // it isn't existed. save a new model, as the seller is not registered on the server 
      let userInfoDict = realmDepartment.toJSON() 

      refDatabase.setValue(userInfoDict) { (error, ref) in 
       if error == nil { 
        self.createPath(realmDepartment) 
       } else { 
        debugPrint(error!.localizedDescription) 
       } 
      } 
     } 
    }) 
} 

次に、パスモデルを作成し、ユーザーアカウント部門にサインアップするために、彼は、データベース内のモデルへの道を見つけることができました。

private func createPath(_ departmentModel: RealmVendor) { 
    let pathRef = FIRDatabase.database().reference().child(FirebaseDatabaseManager.DatabaseMainGateways.departmentsPath.rawValue).child(departmentModel.uid) 
    pathRef.keepSynced(true) 

    references.append(pathRef) 

    let path = PathModel() 
    path.email = departmentModel.email! 
    path.mainVendorUID = departmentModel.mainVendorUID! 

    let pathJSON = path.toJSON() 

    pathRef.setValue(pathJSON) { (error, ref) in 

    } 
} 

ユーザーが部門にアクセスすると、電子メールアドレスとパスワードを入力するフィールドが2つしかありません。彼がメールを入力した後、私は最初に一連の経路でメールの可用性をチェックします(ここでは間違います)。

func searchDepartmentPathModel(_ byEmail: String, success: (() -> Void)?, fail: ((_ error: Error) -> Void)?, notExist: (() -> Void)?) { 

    let query = FIRDatabase.database().reference().child(FirebaseDatabaseManager.DatabaseMainGateways.departmentsPath.rawValue).queryOrdered(byChild: "email").queryEqual(toValue: byEmail) 

    queries.append(query) 

    query.observeSingleEvent(of: .value, with: { (snapshot) in 
     if snapshot.value is NSNull { 
      debugPrint("searchDepartmentPathModel is NSNull there is not department path model", query.debugDescription) 
      notExist?() 
     } else { 
      debugPrint("searchDepartmentPathModel is success", query.debugDescription) 
      guard let _value = snapshot.value else { return } 
      guard let valueDictionary = _value as? [String : [String : Any]] else { return } 
      guard let modelDictionary = valueDictionary.first else { return } 
      guard let path = Mapper<PathModel>().map(JSON: modelDictionary.value) else { return } 

      // Saving department path 
      let realmDepartmentManager = RealmDepartmentManager() 

      realmDepartmentManager.saveDepartmentPath(path: path) 

      success?() 
     } 
    }, withCancel: { (error) in 
     fail?(error) 
    }) 
} 

この検索は、このメールにモデルの道を見つけた場合、ユーザーがすでに登録を返す特定のエラーコード17007(ある場合は、このアカウントでそのエントリを意味するので、私は最初、ユーザーを登録しようとします最初ではありません)、私は通常の入力で他の関数を呼び出します。最初のログインの後、私はモデル部門のIDを置き換えます(最初にIDを作成した後、FirebaseからユーザーIDを設定します)。

我々が得るデータの構造そのものはエラーが2つのシナリオは、私がモデルに方法を見つけることができないという事実にある

{ 
    "departmentsPath" : { 
    "i11uK8erW2OYJPMQnnoOr0vRGca2" : { 
     "email" : "[email protected]", 
     "mainVendorUID" : "V4lHBFY24rXTRrsvbZloYGjJwkZ2" 
    } 
    }, 
    "vendorDepartments" : { 
    "V4lHBFY24rXTRrsvbZloYGjJwkZ2" : { 
     "i11uK8erW2OYJPMQnnoOr0vRGca2" : { 
     "createdAt" : "502381326.78624", 
     "email" : "[email protected]", 
     "information" : { 
      "address" : "3 Temasek Blvd, Suntec City, Suntec City Mall, Singapore 038983", 
      "departmentTitle" : "Apple", 
      "id" : "D8D7CC3A-E8CC-45AF-A71D-AAAB2E5F776F", 
      "location" : { 
      "id" : "D8D7CC3A-E8CC-45AF-A71D-AAAB2E5F776F", 
      "latitude" : 1.2929781, 
      "longitude" : 103.8570364 
      }, 
      "phoneNumber" : "688", 
      "storeManagerID" : "7", 
      "storeManagerName" : "Tim" 
     }, 
     "isCertified" : false, 
     "isMain" : false, 
     "mainVendorUID" : "V4lHBFY24rXTRrsvbZloYGjJwkZ2", 
     "title" : "My Store", 
     "uid" : "i11uK8erW2OYJPMQnnoOr0vRGca2" 
     } 
    } 
    }, 
    "vendors" : { 
    "V4lHBFY24rXTRrsvbZloYGjJwkZ2" : { 
     "createdAt" : "502370885.980612", 
     "departmentsEmails" : { 
     "-KXzuTG8tZx9Fuyx3jJ8" : "[email protected]" 
     }, 
     "displayName" : “Alex”, 
     "email" : “*******@gmail.com", 
     "isCertified" : false, 
     "isMain" : true, 
     "photoPath" : "https://lh6.*****/-*/**/AAAAAAAAAA8/**/s96*c/photo.jpg", 
     "title" : "My Store", 
     "uid" : "V4lHBFY24rXTRrsvbZloYGjJwkZ2" 
    } 
    } 
} 

次nsnullをを返します。最初のシナリオは、ユーザーが最初に部門を訪問し、アカウントから出て再入力しようとしたときに、要求がモデルの方法を見つけることができない場合です。 2番目のシナリオでは、モデル部門を見つけることができません。アカウント部門(最初の訪問とその後の訪問)が出て、ログに記録されていない部門の別のアカウントにログインしようとします。デバイスからアプリケーションを削除するのに役立ちます。

+0

は、電子メールのfirebaseに、そのような何かをインデックス化するためのルールを設定してみてください{ ".indexOn":["email"] } } } 'この形式は、あなたが使用しないことを知っているだけのものです。 – Jad

+0

@Jad私はそのようなルールを持っていますが、ユーザがログインしていないときには記録できないものがあります。 – Alexander

+0

データベースのルートは "departments"ですか? – Jad

答えて

0

別のケースでも同様の動作をした後、ここで説明します。私はいくつかのカテゴリと、標準カテゴリが真を設定するブール値を持っています。私はカテゴリの構造を完全に削除しましたが、インストールされている答えは1またはtrueに戻りましたが、返さなければならなかったのはNSNullでした。私は、問題がキャッシュにあると思った。読んだ後、this topicは私の意見を確認した。この方法でキャッシュを無効にしようとしましたが、Firebase SDK FIRDatabase.database().persistenceEnabled = false(これ以前は値がtrueでした)は、結果キャッシュを降りた後も常に正しいです。 Firebase SDKキャッシュを使用できるように問題を修正する方法を学びたいと思います。 `{ "ルール":{ ".read ":真、 " .WRITE":真、 "部署":

関連する問題