Add Extra Details on Firebase User Table

时光总嘲笑我的痴心妄想 提交于 2019-11-26 01:59:42

Firebase stores the email/password users in a separate location, that you don't have direct access to. You cannot expand the data in this location.

Since many application developers want to access the user data in their application code, it is a common practice to store all users under a /users node inside the application database itself. The disadvantage is that you have to do this yourself. But the positive side of this is that you can store any extra information if you want.

See the Firebase guide on storing user data for sample code. From there:

var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.onAuth(function(authData) {
  if (authData && isNewUser) {
    // save the user's profile into Firebase so we can list users,
    // use them in Security and Firebase Rules, and show profiles
    ref.child("users").child(authData.uid).set({
      provider: authData.provider,
      name: getName(authData)
    });
  }
});

NOTE: This method only works if you are using Firebase Admin SDK and you need to have end point on your server to manage custom tokens

Firebase Admin SDK has an option to create custom tokens with additional claims object, which can contain arbitrary data. This might be useful to store some user related info, like whether the user is premium user or not.

Additional claims data is accessible using auth object.

example

var uid = "some-uid"; //this can be existing user UID
var additionalClaims = {
   premiumAccount: true,
   some-user-property: 'some-value'
};

admin.auth().createCustomToken(uid, additionalClaims)
  .then(function(customToken) {
     // Send token back to client
  })
  .catch(function(error) {
     console.log("Error creating custom token:", error);
});

additionalClaims are also accessible in Firebase security rules.

for more info read Firebase Custom Tokens

Firebase has a fixed set of user properties which can be updated but not added on to.

However you can add small amounts of data with the help of serialization and deserialization using JSON.stringify() and JSON.parse()

And then use any one of the unused properties to store the string

either in DisplayName, or photoURL property. Keep in mind the data that can be added has to be small in size and stored as a string.

And this can be only possible with using the method in the FIREBASE SDK and not the angularfire as illustrated below

var user = firebase.auth().currentUser;

user.updateProfile({
  displayName: "Jane Q. User",
  photoURL: "https://example.com/jane-q-user/profile.jpg"
}).then(function() {
  // Update successful.
}, function(error) {
  // An error happened.
});

You could store more json like data in the photoURL or displaYName variable in the form of string here.

A Firebase User has a fixed set of basic properties—a unique ID, a primary email address, a name and a photo URL—stored in the project's user database, that can be updated by the user (iOS, Android, web). You cannot add other properties to the Firebase User object directly; instead, you can store the additional properties in your Firebase Realtime Database.

My answer is not angular related but I searched quiet a bit to find out how to do it using Polymer and Polymerfire so I add this answer to help people get it done faster than i did.

I had to add a separate node to db as Frank van Puffelen mentioned.

Imports:

<link rel="import" href="../bower_components/polymerfire/firebase-app.html">
<link rel="import" href="../bower_components/polymerfire/firebase-auth.html">
<link rel="import" href="../bower_components/polymerfire/firebase-document.html">

Then place anywhere in your app a <firebase-app> component:

<firebase-app
  name="yourAppName"
  api-key= "{{yourApi}}"
  auth-domain= "{{yourAuthDomain}}"
  database-url= "{{yourDbUrl}}"
>
</firebase-app>

After that you will need to use <firebase-auth> and <firebase-document>:

Template :

<firebase-auth
  id="auth"
  app-name="yourAppName"
  signed-in="{{signedIn}}"
  user="{{user}}">
</firebase-auth>

<firebase-document
  id="document"
  app-name="yourAppName"
  path="{{usersPath}}"  // e.g "/users"
  data="{{userDocument}}">
</firebase-document>

Script:

this._register = function(){
  var formValid = this.querySelector('#register-form').validate();
  var auth = this.querySelector('#auth');
  if(formValid && this.passWordsIdentic){

  //The actual registration
  auth.createUserWithEmailAndPassword(this.email, this.password).then(function(user){
    console.log('auth user registration succes');

    //Example values
    this.userDocument.uid = user.uid;
    this.userDocument.email = user.email;
    this.userDocument.firstName = this.firstName;
    this.userDocument.lastName = this.lastName;
    this.userDocument.userName = this.userName;
    this.$.document.save(this.usersPath).then(() => {
        console.log("custom user registration succes");
        this.$.document.reset();
      });
     }.bind(this)).catch(function(error) {
       var errorCode = error.code;
       var errorMessage = error.message;
       console.log('error: ', errorCode);
     );
    }
  }

And that's it, you may want to take a look at this excellent google codelab which is a good introduction into using firebase with polymer.

Here's a swift version. Your user structure ("table") is like

--users:
-------abc,d@email,com:
---------------email:abc.d@email.com
---------------name: userName
etc.

After you pass the auth FIRAuth.auth()?.createUser you can set the users in database as below:

        let ref = FIRDatabase.database().reference()
        let rootChild = ref.child("users")
        let changedEmailChild = u.email?.lowercased().replacingOccurrences(of: ".", with: ",", options: .literal, range: nil) // Email doesn't support "," firebase doesn't support "."
        let userChild = rootChild.child(changedEmailChild!)
        userChild.child("email").setValue(u.email)
        userChild.child("name").setValue(signup.name)

Please note that method is changed in v4.0.0. Therefore, you need to use the below code to retrieve the user profile:

afAuth.authState.subscribe((user: firebase.User) => { 
  this.displayName = user.displayName;
  this.email = user.email;
  this.photoURL = user.photoURL;
});

The answer from Frank is good, but things are a little different in Angular6/Firebase5/Angularfire5:

Here is my click handler for signing in a user:

this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider()).then((e) => {
      console.log("Log-In Success" + e.additionalUserInfo.profile.name);
      if (e.additionalUserInfo.isNewUser)
        this.addUserToDatabase(/*...*/);
    }).catch((error) => {
      console.log("Log-In Error: Google Sign-In failed");
    });
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!