2016-11-29 3 views
1

Ich habe eine Abteilungsstruktur bei der Eingabe per E-Mail und ein Passwort, ich suche nach einem Modell der Abteilung per E-Mail, aber stieß auf einen Fehler, das Ergebnis kann für die gleichen Daten unterschiedlich sein. Zum Beispiel, wenn der erste Ansatz, die Abfrage das Modell zurückgibt, mit der folgenden Abfrage kann zurückgeben.Firebase gibt unterschiedliche Ergebnisse für dieselbe Abfrage zurück. iOS

Die Datenstruktur der Abteilungen.

{ 
    "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" 
    } 
    } 

Meine Anfrage

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 

}) 

Was das Problem sein könnte und wie man es beheben? Vielen Dank!

UPDATE

Firebase Regeln

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

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

    } 
} 

UPDATE 1

Aufgabe Weiter war es notwendig, um sicherzustellen, dass, wenn wir zum Haupt Anbieter gehen (normal Firebase Benutzer, kann sich mit Google Plus oder einer E-Mail anmelden), um eigene Abteilungen zu erstellen (Benutzer mit besonderen Einschränkungen für die Daten). Firebase erlaubt es nicht, neue Benutzer im System zu registrieren, wenn wir bereits einen Account haben, aber es musste sein, dass der Hauptanbieter seinen Benutzernamen und sein Passwort an seine Abteilung weitergeben konnte. Also habe ich es anders gemacht. Beim Erstellen einer neuen Abteilung (per E-Mail) überprüfe ich zunächst, ob die E-Mail bereits beim Anlegen einer anderen Abteilung in der Liste des Hauptanbieters hinzugefügt wurde.

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) 
    } 
} 

Der nächste Schritt, wenn die Abteilung nicht durch diese E-Mail erstellt wurde, dann füge ich die E-Mail in der Liste der Modelle des Haupt Anbieters

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!) 
     } 
    } 
} 

Dann die Funktion Ich nenne das schaffen erstes Modell der Abteilung.

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) 
       } 
      } 
     } 
    }) 
} 

Dann ein Pfadmodell erstellen, um für ein Benutzerkonto Abteilung anmelden, konnte er den Weg zu Ihrem Modell in der Datenbank finden.

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 

    } 
} 

Dann, wenn ein Benutzer eine Abteilung besucht, dann hat er nur zwei Felder, das Feld eingeben E-Mail-Adresse und Ihr Passwort ein. Nachdem er seine E-Mail-Adresse eingegeben hat, überprüfe ich zunächst die Verfügbarkeit von E-Mails in einer Reihe von Pfaden (im Folgenden Fehler).

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) 
    }) 
} 

Wenn diese Suche ein Modell Art und Weise mit diesem findet eine E-Mail, werde ich zunächst versuchen, den Benutzer zu registrieren, denn wenn der Benutzer bereits Gibt einen spezifischen Fehlercode 17007 registriert ist (dies bedeutet, dass der Eintrag auf dem Konto ist nicht der erste), ich werde andere Funktionen mit den üblichen Eingaben aufrufen. Nach der ersten Anmeldung ersetze ich die ID der Modellabteilung (wenn ich zum ersten Mal Ihre ID erzeuge, erzeuge ich die Benutzer-ID von Firebase).

Die Struktur der Daten, die wir die folgenden

{ 
    "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" 
    } 
    } 
} 

Der Fehler liegt in der Tatsache erhalten, dass die beiden Szenarien ich nicht Möglichkeiten, um Modell finden kehrt NSNull. Das erste Szenario ist, wenn ein Benutzer zum ersten Mal eine Abteilung besucht und aus dem Konto herauskommt und versucht, sie erneut einzugeben, kann die Anfrage keinen Modellweg finden. Im zweiten Szenario können Sie keine Modellierungsmöglichkeiten finden, wenn Sie zum Account Department (dem ersten und den nachfolgenden Besuchen) gehen und versuchen, sich bei einem anderen Account in der Abteilung anzumelden, der nicht protokolliert wurde. Hilft nur die Anwendung von einem Gerät zu löschen.

+0

versuchen, für die E-Mail, so etwas wie, dass eine Regel für die Indizierung in Feuerbasis zu setzen: '{ "Regeln": { ".mehr ": true, " .WRITE": true, "Abteilungen": { ".IndexOn": ["E-Mail"] } } } 'aber dieses Format nur für Sie zu wissen, nicht zu verwenden. – Jad

+0

@Jad Ich habe solche Regeln, aber eine, die nicht aufgezeichnet werden kann, wenn der Benutzer nicht angemeldet ist. – Alexander

+0

und der Stamm für die Datenbank ist "Abteilungen"? – Jad

Antwort

0

Nach einem ähnlichen Verhalten in einem anderen Fall, beschreibe ich es jetzt. Ich habe mehrere Kategorien und einen booleschen Wert, den die Standardkategorien als wahr festlegen. Ich habe nur die Struktur der Kategorien komplett entfernt, aber ich kam die Antwort 1 oder wahr zurück, die sie installiert sind, aber mussten zurückgeben. Ich dachte, dass das Problem im Cache ist, nach dem Lesen this topic bestätigte meine Meinung. Ich habe versucht, den Cache auf diese Weise zu deaktivieren Firebase SDK FIRDatabase.database().persistenceEnabled = false (Zuvor war der Wert wahr), nach dem Aussteigen aus dem Ergebnis-Cache ist immer richtig. Ich möchte erfahren, wie Sie das Problem beheben können, so dass Sie den Firebase SDK-Cache verwenden können.

Verwandte Themen