Reputation:
I've created an app in which, when the user signs up, should create two values in the Firestore server in the user's document, that is level and subjects (meaning it's in /users/userid).
I've tried manually creating the 'users' collection, but nothing is being created when the user signs up.
The following is my code (SignUpViewController):
import Firebase
var reference: DocumentReference!
func firebaseAuth() {
let userDisplayName = textfieldDisplayName.text!
let userEmail = textfieldEmail.text!
let userPassword = textfieldPassword.text!
if userEmail == "" || userPassword == "" {
labelMessage.isHidden = false
labelMessage.textColor = UIColor.red
labelMessage.text = "Error: A compulsory field is left blank."
} else {
Auth.auth().createUser(withEmail: userEmail, password: userPassword) { (user, error) in
if user != nil && error == nil {
let changeRequest = Auth.auth().currentUser?.createProfileChangeRequest()
changeRequest?.displayName = userDisplayName
changeRequest?.commitChanges(completion: { (error) in
if error == nil {
let userID = Auth.auth().currentUser?.uid
let dataToSave: [String: Any] = ["level":0, "subjects":[""]]
self.reference = Firestore.firestore().collection("users").document(userID ?? "")
self.reference.setData(dataToSave, completion: { (error) in
if error == nil {
self.performSegue(withIdentifier: "presentInitial", sender: self)
} else {
self.labelMessage.isHidden = false
self.labelMessage.textColor = UIColor.red
self.labelMessage.text = "Error: \(error?.localizedDescription ?? "")"
}
})
self.performSegue(withIdentifier: "presentInitial", sender: self)
} else {
self.labelMessage.isHidden = false
self.labelMessage.textColor = UIColor.red
self.labelMessage.text = "Error: \(error?.localizedDescription ?? "")"
}
})
} else {
self.labelMessage.isHidden = false
self.labelMessage.textColor = UIColor.red
self.labelMessage.text = "Error: \(error?.localizedDescription ?? "")"
}
}
}
}
The following code is from another View Controller which SignUpViewController redirects to (HomeViewController):
import Firebase
var reference: DocumentReference!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let userID = Auth.auth().currentUser?.uid
reference.getDocument { (docSnapshot, error) in // Fatal error occured here
let data = docSnapshot?.data()
let userLevel = data?["level"] as? String ?? ""
if userLevel == "" {
self.performSegue(withIdentifier: "performSetup", sender: self)
}
}
}
I expected that when redirected to the homepage (segued through presentInitial), the homepage will then read the value of 'level'. However, the app crashed with a fatal error: "Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value" where 'level' was meant to be read from the server.
Upvotes: 0
Views: 78
Reputation: 594
I think the problem is not with Firestore. According to the error message, the code wraps an optional value but failed because it is nil
, so the problem is probably about these three lines:
let userDisplayName = textfieldDisplayName.text!
let userEmail = textfieldEmail.text!
let userPassword = textfieldPassword.text!
Sometimes, when a UITextField
has no text, its text
is nil
instead of ""
, which may cause the problem. You can replace the three lines with the following:
let userDisplayName = textfieldDisplayName.text ?? ""
let userEmail = textfieldEmail.text ?? ""
let userPassword = textfieldPassword.text ?? ""
In this way, these three variables will always be ""
when there are no text, and your logic of checking blank fields will still work.
Edit: For future reference, the real problem is not in the question but in the comments of this answer.
Upvotes: 1
Reputation: 466
Did you check your database rules ? you need to setup the rules when to work and when not to so no one can access the database but your apps for a test now use this code to verify it woks then you should change it
{
"rules": {
".read": true,
".write": true
}
}
Upvotes: 0