how to get user information other than user name with Firebase Authentification

Viewed 99

I'm an English teacher in Japan. I'm developing a web app using Firebase Hosting

My students have Google account because we use Gsuite for Education, so I decided to get students' data with Firebase Auth.

function signIn(){
  var provider = new firebase.auth.GoogleAuthProvider();
  firebase.auth().signInWithPopup(provider);
}
function saveMessage() {
  // Add a new message entry to the Firebase database.
  firebase.firestore().collection('messages').add({
      name: firebase.auth().currentUser.displayName,
      text: messageInputElement.value,
      timestamp: firebase.firestore.FieldValue.serverTimestamp()
  })

In saveMessage function I get user's name with firebase.auth().currentUser.displayName

Is it possible to get more user information? For example, I want User's school name, class number and student number. I read Firebase Auth document. https://firebase.google.com/docs/reference/js/firebase.User#providerdata This seems to be good. However I couldn't understand how to use it.

Could you tell me how to get user information other than user name with Firebase Auth?


This is index.html

<!doctype html>
<html lang="ja">
   <head>
      <title>音読アプリ アドバンス</title>
   </head>

   <body>
      <input id="sign-in" type="submit" value="SignIn">
      <br>
      <textarea id="text"></textarea>
      <br>
      <input id="download" type="submit" value="download">
      <div id='player'></div>

      <!-- Import and configure the Firebase SDK -->
      <!-- These scripts are made available when the app is served or deployed on Firebase Hosting -->
      <script src="/__/firebase/7.14.3/firebase-app.js"></script>
      <script src="/__/firebase/7.14.3/firebase-auth.js"></script>
      <script src="/__/firebase/7.14.3/firebase-storage.js"></script>
      <script src="/__/firebase/7.14.3/firebase-messaging.js"></script>
      <script src="/__/firebase/7.14.3/firebase-firestore.js"></script>
      <script src="/__/firebase/7.14.3/firebase-performance.js"></script>
      <script src="/__/firebase/7.14.3/firebase-functions.js"></script>
      <script src="/__/firebase/init.js"></script>

      <script src="scripts/main.js"></script>
   </body>
</html>

This is main.js (client-side)

'use strict';
function signIn(){
  var provider = new firebase.auth.GoogleAuthProvider();
  firebase.auth().signInWithPopup(provider);
}
function saveMessage() {
  // Add a new message entry to the Firebase database.
  firebase.firestore().collection('messages').add({
      name: firebase.auth().currentUser.displayName,
      text: messageInputElement.value,
      timestamp: firebase.firestore.FieldValue.serverTimestamp()
  })
      .then(docRef => {

          this.firestoreDocListener = docRef.onSnapshot(doc => {
              if (doc.exists && doc.data().hasOwnProperty('fileName')) {
                  console.log(doc.data().fileName);
                  // Use doc.data().fileName the way you need!
                  // Create a reference from a Google Cloud Storage URI
                  var storage = firebase.storage();
                  var pathReference = storage.ref(doc.data().fileName)
                  pathReference.getDownloadURL().then(function(url) {
                    console.log(url);
                    const audio = document.createElement('AUDIO');
                    audio.controls = true;
                    audio.src = url;
                    const player = document.getElementById('player');
                    player.appendChild(audio);
                  }).catch(function(error) {
                    // A full list of error codes is available at
                    // https://firebase.google.com/docs/storage/web/handle-errors
                    switch (error.code) {
                      case 'storage/object-not-found':
                        console.log('storage/object-not-found')
                        break;

                      case 'storage/unauthorized':
                        console.log('storage/unauthorized')
                        break;

                      case 'storage/canceled':
                        console.log('storage/canceled')
                        break;

                      case 'storage/unknown':
                        console.log('storage/unknown')
                        break;
                    }  
                  });

              }
          });

      })
      .catch(function (error) {
          console.error('Error writing new message to Firebase Database', error);
      });
}

// Checks that the Firebase SDK has been correctly setup and configured.
function checkSetup() {
  if (!window.firebase || !(firebase.app instanceof Function) || !firebase.app().options) {
    window.alert('You have not configured and imported the Firebase SDK. ' +
        'Make sure you go through the codelab setup instructions and make ' +
        'sure you are running the codelab using `firebase serve`');
  }
}

// Checks that Firebase has been imported.
checkSetup();

// Shortcuts to DOM Elements.
var messageInputElement = document.getElementById('text');
var submitButtonElement = document.getElementById('download');
var signInButtonElement =document.getElementById('sign-in');


// Saves message on form submit.
submitButtonElement.addEventListener('click', saveMessage);
signInButtonElement.addEventListener('click', signIn);

This is index.js (server-side cloud functions)

const functions = require('firebase-functions');
var admin = require("firebase-admin");
admin.initializeApp();
const textToSpeech = require('@google-cloud/text-to-speech');
require('date-utils');

exports.myFunction = functions.firestore
    .document('messages/{id}')
    .onCreate(async (snap) => {   // See the async here

        try {    //See the "global" try/catch

            const client = new textToSpeech.TextToSpeechClient();

            // The text to synthesize
            const newValue = snap.data();
            const text = newValue.text;

            // Construct the request
            const request = {
                input: { text: text },
                // Select the language and SSML voice gender (optional)
                voice: { languageCode: 'en-US', ssmlGender: 'NEUTRAL' },
                // select the type of audio encoding
                audioConfig: { audioEncoding: 'MP3' },
            };


            var bucket = admin.storage().bucket('adv********.appspot.com');
            var dt = new Date();
            var formatted = dt.toFormat('YYYYMMDDHH24MISS');
            var file = bucket.file('audio/' + formatted + '.mp3');
            // Create the file metadata
            var metadata = {
                contentType: 'audio/mpeg'
            };

            // Performs the text-to-speech request
            const [response] = await client.synthesizeSpeech(request);
            await file.save(response.audioContent, metadata);
            console.log("File written to Firebase Storage.");

            await snap.ref.update({ fileName: 'audio/' + formatted + '.mp3' });

            return null;

        } catch (error) {
            console.error(error);
        }

    });
2 Answers

Firebase Authentication only knows about the information that you see in the User and UserInfo objects, and nothing more. Even then, some data might be missing. Auth doesn't have direct access to everything that the provider could possibly know about the person signin in. You would have to somehow query the provider directly using its own APIs, or have the student enter their information and store that in a database (Firebase Auth will not store arbitrary user information.)

You will need to create a custom form on your front end that gathers that data and save those details after creating of the user, possibly in a function like so:

function writeUserData(userId, name, fav_color, best_friend, best_hero) {
  firebase.database().ref('users/' + userId).set({
    name: name,
    fav_color: fav_color,
    best_friend : best_friend,
    best_hero: best_hero
  });
}

You then typically would structure your database like so:

"users": {
    "$userID": {
        "name": "John",
        "fav_color": "chartruese",
        "best_friend": "James",
        "best_hero": "spiderman"
    }
}

Just a note, You usually would post this data after the user is authenticated, that way you can add a firebase rule to make sure that only that user can post and read that data.

Related