1

I want to create a user that will be able to authenticate in firebase and then to insert the user's data in the database. The code i am using is the following:

this.app.auth().createUserWithEmailAndPassword(userForm.value.email, userForm.value.password)
        .then(res => {
            console.log('2 form data:', userForm.value);
            this._firebase.app.database().ref('users').push({
                email: userForm.value.email,
                uid: res.uid
            })
        })
        .catch(err => {
            console.log('Something went wrong:', err.message);
        });

i am using app to insert the user in authentication and _firebase to insert the user's data to database. The createUserWithEmailAndPassword works but i get the following error:

Reference.push failed: first argument contains undefined in property 'users.email'

userForm contains the user data. What could be wrong?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Elias
  • 347
  • 2
  • 5
  • 20
  • What do you see in the console if you do console.log({ email: userForm.value.email, uid: res.uid }) before this._firebase.app.database().ref('users').push ?? – Renaud Tarnec May 05 '18 at 22:10
  • I see this: Object { email: undefined, uid: "hguE4Qnh0VN0NI4NWlDr188A8Xt2" } the email is undefined, so all the form data are undefined. Is there any solution for this? – Elias May 06 '18 at 06:10
  • Your email value is undefined, hence the error message you get. You should get the correct value from the form. You might follow the answer of Muiz Mahdy. (I am not qualified with Angular, I'm sorry I can't help further) – Renaud Tarnec May 06 '18 at 07:51
  • it seems that in the .then({}) all the form data are undefined. how could this be possible? the email and password given in the form are inserted in authentication – Elias May 06 '18 at 09:27
  • Have you tried Muiz Mahdy's answer? – Renaud Tarnec May 06 '18 at 09:28
  • Ok, I think I got the problem, I will write an answer. Just hold on. – Renaud Tarnec May 06 '18 at 09:30

3 Answers3

1

Do as follow:

this.app.auth().createUserWithEmailAndPassword(userForm.value.email, userForm.value.password)
    .then(res => {
        console.log('2 form data:', userForm.value);

        var user = firebase.auth().currentUser;

        console.log(user.email);
        console.log(user.uid);

        return this._firebase.app.database().ref('users').push({
            email: user.email,
            uid: user.uid
        })
    })
    .catch(err => {
        console.log('Something went wrong:', err.message);
    });

It is normal that you don't get the parameters passed to the function in the then. The asynchronous function createUserWithEmailAndPassword "returns a firebase.Promise containing non-null firebase.auth.UserCredential" see https://firebase.google.com/docs/reference/js/firebase.auth.Auth#signInWithEmailAndPassword

So you have to get the current user in the then function, with firebase.auth().currentUser;


EDIT following your comment (edit2: which was deleted :-))

Do a function like that, and call it with the data of the userForm:

function pushUser(userForm.value) {

    //create a JavaScript object holding the values you want to push to Firebase

    const objectToPush = {
        email: userForm.value.email,
        uid: userForm.value.uid,
        address: userForm.value.address,
        .....
    };

    return this.app.auth().createUserWithEmailAndPassword(userForm.value.email, userForm.value.password)
    .then(res => {

       //var user = firebase.auth().currentUser;  <- you don't need that anymore 
       //since you have the values in the object

        return this._firebase.app.database().ref('users').push(objectToPush);
    })
    .catch(err => {
        console.log('Something went wrong:', err.message);
    });

}

PS: take care that the this still refers to what you want.

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • This worked!!! Thank you very much for your help!!! I also added the uid taken from res: .then(res => { objectToPush.uid = res.uid; return this._firebaseAuth.app.database().ref('users').push(objectToPush); }) – Elias May 06 '18 at 10:33
  • can you please check this? https://stackoverflow.com/questions/50610498/get-user-role-from-database-based-on-user-id-in-angular/50611029?noredirect=1#comment88268539_50611029 – Elias Jun 01 '18 at 05:32
0

I can't comment so i will put my answer here,

this._firebase.app.database().ref('users').push

this is not referring to the firebase so you need to define in the begining of the function vat that = this and then chagne your code to this:

that._firebase.app.database().ref('users').push
T.sagiv
  • 325
  • 2
  • 9
  • The corrected part is this: `return this.app.auth().createUserWithEmailAndPassword(userForm.value.email, userForm.value.password) .then(res => { objectToPush.uid = res.uid; return this._firebaseAuth.app.database().ref('users').push(objectToPush); }) .catch(err => { console.log('Something went wrong:', err.message); });` You can see Renaud's answer above – Elias May 06 '18 at 14:32
0

The issue seems to be in 'userForm.value.email'.

The simplest way to get a form input is to use two-way binding with ngModel.

If you're using Reactive Forms, then use:

emailVal:string = this.formGroup.get('emailCtrl').value;

to get the value of a form control (emailCtrl) of a form group (formGroup)

Muizz Mahdy
  • 798
  • 2
  • 8
  • 24
  • i am not using reactive forms, but this.app.auth().createUserWithEmailAndPassword(userForm.value.email, userForm.value.password) works, the email and password are inserted in the authentication. these values are taken from the form. how can they be undefined 2 lines below this? – Elias May 06 '18 at 09:30