私は電子メールとパスワードで入力する際に部門の構造を持っていますが、電子メールで部門のモデルを探していますが、エラーが発生しました。たとえば、最初のアプローチでは、クエリがモデルを返し、次のクエリで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番目のシナリオでは、モデル部門を見つけることができません。アカウント部門(最初の訪問とその後の訪問)が出て、ログに記録されていない部門の別のアカウントにログインしようとします。デバイスからアプリケーションを削除するのに役立ちます。
は、電子メールのfirebaseに、そのような何かをインデックス化するためのルールを設定してみてください{ ".indexOn":["email"] } } } 'この形式は、あなたが使用しないことを知っているだけのものです。 – Jad
@Jad私はそのようなルールを持っていますが、ユーザがログインしていないときには記録できないものがあります。 – Alexander
データベースのルートは "departments"ですか? – Jad