Я создаю приложение, в котором используется функция входа и пароля Firebase. У меня зарегистрирован пользователь с именем пользователя, электронной почтой и паролем. Я борюсь с тем, как остановить пользователя от создания, если имя пользователя не уникально. Я читал другие вопросы (в частности, Firebase-android-make-username-unique и how-prevent-username-from-duplicate-signup-infirebase), но я до сих пор не получил его для полной работы.Firebase iOS Swift: предотвратить дублирование имен пользователей
Я следовал инструкциям в первой ссылке выше и настроить свою структуру данных, как:
app : {
users: {
"some-user-uid": {
email: "[email protected]"
username: "myname"
}
},
usernames: {
"myname": "some-user-uid"
}
}
и мои правила безопасности, как:
"users": {
"$uid": {
".write": "auth !== null && auth.uid === $uid",
".read": "auth !== null && auth.provider === 'password'",
"username": {
".validate": "
!root.child('usernames').child(newData.val()).exists() ||
root.child('usernames').child(newData.val()).val() == $uid"
}
}
}
С этой установкой, если я пытаюсь создать новый пользователь с именем пользователя, которое уже существует, не позволяет пользователю добавлять в мою структуру данных. Когда вызывается следующий код, он печатает «Пользовательские данные не могут быть сохранены», если имя пользователя является дубликатом.
func createNewAccount(uid: String, user: Dictionary<String, String>) {
USER_REF.childByAppendingPath(uid).setValue(user, withCompletionBlock: {
(error:NSError?, ref:Firebase!) in
if (error != nil) {
print("User Data could not be saved.")
} else {
print("User Data saved successfully!")
}
})
}
func addUsernameToUsernamePath (userData: Dictionary<String, String>) {
USERNAME_REF.updateChildValues(userData)
}
Здесь я застрял. Мой метод создания учетной записи ниже не вызывает вышеупомянутые два метода до тех пор, пока не будут вызваны createUser и authUser (для чего мне нужно получить uid). Моя проблема заключается в том, что пользователь по-прежнему создается как зарегистрированный пользователь, и мои правила безопасности просто не позволяют пользователям добавлять информацию в мою структуру данных. Мне нужно выяснить, как остановить создание пользователя, если есть дублируемое имя пользователя.
@IBAction func createAccount() {
let username = usernameField.text
let email = emailField.text
let password = passwordField.text
if username != "" && email != "" && password != "" {
// Set Email and Password for the New User.
DataService.dataService.BASE_REF.createUser(email, password: password, withValueCompletionBlock: { error, result in
if error != nil {
print("Error: \(error)")
if let errorCode = FAuthenticationError(rawValue: error.code) {
switch (errorCode) {
case .EmailTaken:
self.signupErrorAlert("Email In Use", message: "An account has already been created for this email address.")
default:
self.signupErrorAlert("Oops!", message: "Having some trouble creating your account. Please try again or check your internet connection.")
}
}
} else {
DataService.dataService.BASE_REF.authUser(email, password: password, withCompletionBlock: {
err, authData in
let user = ["provider": authData.provider!, "email": email!, "username": username!]
let userData = [username!: authData.uid!]
DataService.dataService.createNewAccount(authData.uid, user: user)
DataService.dataService.addUsernameToUsernamePath(userData)
})
EDIT
Вот мой обновленный метод Createaccount, что решить мою проблему.
@IBAction func createAccount() {
let username = usernameField.text
let email = emailField.text
let password = passwordField.text
if username != "" && email != "" && password != "" {
DataService.dataService.USERNAME_REF.observeEventType(.Value, withBlock: { snapshot in
var usernamesMatched = false
if snapshot.value is NSNull {
usernamesMatched = false
} else {
let usernameDictionary = snapshot.value
let usernameArray = Array(usernameDictionary.allKeys as! [String])
for storedUserName in usernameArray {
if storedUserName == self.usernameField.text! {
usernamesMatched = true
self.signupErrorAlert("Username Already Taken", message: "Please try a different username")
}
}
}
if !usernamesMatched {
// Set Email and Password for the New User.
DataService.dataService.BASE_REF.createUser(email, password: password, withValueCompletionBlock: { error, result in
if error != nil {
print("Error: \(error)")
if let errorCode = FAuthenticationError(rawValue: error.code) {
switch (errorCode) {
case .EmailTaken:
self.signupErrorAlert("Email In Use", message: "An account has already been created for this email address.")
default:
self.signupErrorAlert("Oops!", message: "Having some trouble creating your account. Please try again or check your internet connection.")
}
}
} else {
// Create and Login the New User with authUser
DataService.dataService.BASE_REF.authUser(email, password: password, withCompletionBlock: {
err, authData in
let user = ["provider": authData.provider!, "email": email!, "username": username!]
let userData = [username!: authData.uid!]
// Seal the deal in DataService.swift.
DataService.dataService.createNewAccount(authData.uid, user: user)
DataService.dataService.addUsernameToUsernamePath(userData)
})
Подтвердить, что имя пользователя не существует до вызова createUser()? – Kato
Спасибо за предложение. Я только что обновил свой код и, похоже, решил проблему. – chickenparm
Почему вы не проверяете имя пользователя с двойным именем, через createUser-> FAuthenticationErrorEmailTaken, а если оно доступно, то создайте пользователя в узле/users? Если вы сделаете это, вы можете уменьшить этот код до нескольких строк, так как это имя пользователя не будет уже существовать в вашем/пользовательском узле. – Jay