10

How can I add extra attributes phone number and address to this data set? It seems like Firebase documentation doesn't specify anything about that.

I have implemented the login, register and update using firebase.auth()

Login :

//Email Login
firebase.auth().signInWithEmailAndPassword(email, password).then(
   ok => {
        console.log("Logged in User",ok.user);              
    },
    error => {
        console.log("email/pass sign in error", error);
    }
);

Register:

 //Sign Up
firebase.auth().createUserWithEmailAndPassword(email, password).then(
    ok => {
        console.log("Register OK", ok);
    },
    error => {
        console.log("Register error", error);
    }
)

Update:

//User Authentication
firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    $scope.data=user;
  } else {
    // No user, Redirect to login page
  }
});

//Save Function
$scope.save=function(values){

    $scope.data.updateProfile({

      displayName: "Test User",
      email: "test@gmail.com",
     /* phone: 123412341,
      address: "Temp Address",*/
      photoURL: "www.example.com/profile/img.jpg"

    }).then(function() {

     // Update successful.

    }, function(error) {

     // An error happened.

    }); 

};  
devlin carnate
  • 8,309
  • 7
  • 48
  • 82
Arjun Sunil Kumar
  • 1,781
  • 3
  • 28
  • 46
  • This one is a nice implementation: http://stackoverflow.com/questions/32151178/how-do-you-include-a-username-when-storing-email-and-password-using-firebase-ba – Arjun Sunil Kumar Jun 22 '16 at 00:31
  • Yes, that's the Firebase implementation. But it is limited to only these properties: https://firebase.google.com/docs/reference/ios/firebaseauth/interface_f_i_r_user#properties In the link I posted in the comment to my answer they talk about this ;) – Devid Farinelli Jun 22 '16 at 15:37

3 Answers3

8

As far as I know, you have to manage the users profiles by yourself if you want to have more fields than the default user provided by Firebase.

You can do this creating a reference in Firebase to keep all the users profiles.

users: {
  "userID1": {
    "name":"user 1",
    "gender": "male" 
  },
  "userID2": {
    "name":"user 2",
    "gender": "female" 
  }
}

You can use onAuthStateChanged to detect when the user is logged in, and if it is you can use once() to retrieve user's data

firebaseRef.child('users').child(user.uid).once('value', callback)

Hope it helps

Devid Farinelli
  • 7,514
  • 9
  • 42
  • 73
  • Currently this is a good solution. But i would be glad to know if there are any better solutions for the same – Arjun Sunil Kumar Jun 21 '16 at 12:02
  • 1
    This is the suggested way to do this. A better solution could be a solution that better fits your needs. You should structure your data depending on how you want to retrieve them. For example, if you want to keep some info secret you can do: "userId":{ "credit-card":"0000", "public":{"name":"Devid","genere":"dragon"}} and use the security rules to allow other users to only read the "public" node. Hope it helps :) I'm here for any other question – Devid Farinelli Jun 21 '16 at 12:36
  • This answer could be helpful: http://stackoverflow.com/a/37420701/4695325 – Devid Farinelli Jun 21 '16 at 12:39
2

This can be done by directly storing your custom data in Firebase Auth as "custom claims" on each user via the Admin SDK on your backend.

Note this can't be done purely client-side, your server (or you can use a Cloud Function as per the linked guide if you don't already have a server/API set up) needs to make a request through the Admin SDK to securely set the data using the admin.auth().setCustomUserClaims() method:

https://firebase.google.com/docs/auth/admin/custom-claims#defining_roles_via_an_http_request

wyqydsyq
  • 1,992
  • 1
  • 20
  • 28
  • This is exactly what I was looking for. Whilst my use case is different to the one in the question (needed to store a UID from another system against a user) this is perfect. Basically storing custom metadata against the auth records. – Jacob Wood Mar 08 '21 at 13:27
0

You could write some code that combines data from firebase auth and firestore document and expose that to the app as a single data entity. To take subscriptions and notify that changes to the whole app, you would be better served with event libraries like Rxjs. Bellow, I wrote the example below using a simple library that implements an event bus.

// auth.js
import { publish } from '@joaomelo/bus'
import { fireauth, firestore } from './init-firebase.js'

const authState = {
  userData: null
};

fireauth.onAuthStateChanged(user => {
  if (!user) {
    authState.userData = null;
    publish('AUTH_STATE_CHANGED', { ...authState });
    return;
  }

  // we must be carefull
  // maybe this doc does not exists yet
  const docRef = firestore
    .collection('profiles')
    .doc(user.uid);

  docRef
    // 'set' secures doc creation without 
    // affecting any preexisting data
    .set({}, { merge: true }) 
    .then(() => { 
      docRef.onSnapshot(doc => {
        // the first data load
        // and subsequent updates
        // will trigger this
        authState.userData = {
          id: user.uid, 
          email: user.email,
          ...doc.data()
        };
        publish('AUTH_STATE_CHANGED', { ...authState });
      });
    });  
});

// some-place-else.js
import { subscribe } from '@joaomelo/bus'
subscribe('AUTH_STATE_CHANGED', 
  authState => console.log(authState));

You can expand on that in a post I wrote detailing this solution and also talking about how to update those properties. There is too a small library that encapsulates the answer with some other minor features with code you could check.

João Melo
  • 784
  • 6
  • 16