2016-11-29 209 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缓存。

相关问题