2016-11-29 157 views
1

我通過電子郵件和密碼輸入時有一個部門結構,我正在通過電子郵件查找部門模型,但遇到錯誤,結果可能會因相同的數據而不同。例如,如果第一種方法,查詢返回模型,用以下查詢可返回NSNullFirebase針對相同的查詢返回不同的結果。 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

火力地堡規則

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

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

    } 
} 

更新1

任務接下來,有必要確保我們去的時候主要供應商(正常火力地堡用戶誰可以使用Google plus或電子郵件登錄)給用戶以創建他們自己的部門(對數據有特殊限制的用戶)。如果我們已經有一個帳戶,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 

    } 
} 

然後,當用戶訪問一個部門時,他只有兩個字段,該字段輸入電子郵件地址和密碼。在他輸入他的電子郵件之後,我首先通過一系列路徑檢查電子郵件的可用性(以下簡稱錯誤)。

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

我們得到的數據非常結構如下

{ 
    "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。第一種情況是,當用戶第一次訪問某個部門時,出現該帳戶並且正在嘗試重新輸入,該請求無法找到模型方式。第二種情況是,如果您訪問賬戶部門(第一次和後續訪問),您無法找到建模的方法,並嘗試登錄部門中尚未記錄的其他賬戶。幫助只從設備上刪除應用程序。

+0

嘗試設置索引規則在火力的電子郵件,類似的東西:'{ 「規則」:{ 「.read 」:真實, 「 .WRITE」:真實, 「部門」:{ 「.indexOn」:[「email」] } } }'但這種格式只是爲了讓您知道不要使用。 – Jad

+0

@Jad我有這樣的規則,但在用戶未登錄時無法記錄。 – Alexander

+0

和數據庫的根目錄是「部門」? – Jad

回答

0

在另一種情況下,類似的行爲後,現在我描述它。我有幾個類別,以及一個標準類別設置爲true的布爾值。我只是完全刪除了類別的結構,但我回來了答案1或者真,他們安裝了,但不得不返回NSNull。我認爲問題是在緩存中,看完this topic後證實了我的意見。我嘗試以這種方式禁用緩存,Firebase SDK FIRDatabase.database().persistenceEnabled = false(在此之前,該值爲true)在獲得結果緩存後總是正確的。我想了解如何解決該問題,以便您可以使用Firebase SDK緩存。

相關問題