user11616872
user11616872

Reputation:

Firestore database does not store data

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

Answers (2)

KeroppiMomo
KeroppiMomo

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

Marchal
Marchal

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

firebase rules

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Upvotes: 0

Related Questions