Friday, 7 April 2017

Linking External accounts with Firebase Auth + Firebase DB

I use Firebase Auth to manage my users and tie them to my Firebase DB to store their data. When trying to make updates to the Firebse DB users I frequently find myself doing things like this:

const USERS = firebase.database().ref(`users`);
let provider = new firebase.auth.GoogleAuthProvider();

firebase.auth().currentUser.linkWithPopup(provider).then(function(result) {
    // Accounts successfully linked.
    let credential = result.credential;
    let user = result.user;
    let key = '';
    let userRef = '';


    USERS.orderByChild('uid').equalTo(user.uid).once('value').then(snapshot => {
        snapshot.forEach((child) => {
            key = child.key;
            userRef = firebase.database().ref(`users/${key}`);
            let updatedUser = {};

            userRef.update({
                linkedAccounts: user.providerData
            });

            userRef.once('value').then(snapshot => {
                updatedUser = snapshot.val();

                dispatch({
                    action: LINK_GOOGLE,
                    payload: updatedUser
                });
            });

            return;
        });
    });

}).catch(function(error) {
    // Handle Errors here.
    dispatch(authError(error));
});

In this example I'm linking a new Auth provider (Google). On the client side I need to then disable the button so I will do some checks to sort out whether the user has this data etc. I'm using react/redux so I call dispatch() to send the action and the client will be updated with the new user in the application's state. This is all working (to an extent), however, I have a couple questions...

1. In this example updatedUser does not contain the key for the user. Meaning it looks like:

{ displayName: 'Frank Smith', photoUrl: '', uid: 12345 }

... when what I want is the whole object like:

'-F12345asdfg': { displayName: 'Frank Smith', photoUrl: '', uid: 12345 }

... with the key included to remain consistent with the way the data is returned elsewhere. I know I can make a second FB DB call to get the user by the uid (like above) which will return it the way I want it but it seems so inefficient...

2. Is this the most efficient/effective way to do this? This seems very messy.

Thanks in advance!



via Alec Sibilia

No comments:

Post a Comment