Building my first Mobile App - Part 3: Adding authentication with firebase

4 min read

Next I am going to add authentication with Firebase. I’ll leverage the react-native-firebase library.

Installing firebase in React Native

First, I have to install the base package.

npm install --save @react-native-firebase/app

To connect firebase to my Android app, I also had to follow the instructions here up till Step 3.

Adding anonymous authentication

To do this, I had to install the auth module.

npm install --save @react-native-firebase/auth

I’ve decided to sign people in anonymously. Because, I want to keep each user’s data separate on firestore, and it would very much help when creating access control rules to have uniques UID generated for the users.

Also, if (or when?) a user creates a proper account, the anonymous account can be linked to it.

So, I modified App.js to log the user in before displaying the homepage

// App.js
import React from 'react';
import Icon from 'react-native-vector-icons/FontAwesome';

import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs';

import { createAppContainer } from 'react-navigation';
import { Provider as PaperProvider } from 'react-native-paper';
import { HomeScreen } from './views/home';
import { ContactsScreen } from './views/contacts';
import { LoadingScreen } from './views/loading';

import firebase from '@react-native-firebase/app';
import '@react-native-firebase/auth';

const AppNavigator = createMaterialBottomTabNavigator(
  {
    Home: {
      screen: HomeScreen,
      navigationOptions: {
        tabBarIcon: ({ tintColor }) => (
          <Icon name="home" size={20} color={tintColor} />
        )
      }
    },
    Contacts: {
      screen: ContactsScreen,
      navigationOptions: {
        tabBarIcon: ({ tintColor }) => (
          <Icon name="users" size={20} color={tintColor} />
        )
      }
    },
  },
  {
    initialRouteName: 'Home',
    activeColor: '#000000',
    inactiveColor: 'rgba(0, 0, 0, 0.54);',
    barStyle: { backgroundColor: '#FFEB3B' },
  }
);

const AppContainer = createAppContainer(AppNavigator);

export default class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {};
  }

  onAuthStateChanged(user) {
    this.setState({ user });
  }

  componentDidMount() {
    firebase.auth().onAuthStateChanged(
      this.onAuthStateChanged.bind(this)
    );

    firebase.auth().signInAnonymously().catch((e) => {
      console.error(e);
    })
  }

  render() {
    let screen;

    if (this.state.user) {
      screen = <AppContainer />;
    } else {
      screen = <LoadingScreen />;
    }

    return (
      <PaperProvider>
        {screen}
      </PaperProvider>
    );
  }

}

Adding a loading screen

In the new App.js, I added a loading screen that shows while the user is still being logged in. So, I also have to create that screen.

// .views/loading.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
    },
});

export class LoadingScreen extends React.Component {
    render() {
        return (
            <View style={styles.container}>
                <Text>Loading!!!</Text>
            </View>
        );
    }
}

Merging screens to a single module

Right now, I have 3 screens, and I’m importing all 3 of them into App.js. To me, it’s already looking a little messy.

So, I’m going to create a screens module and import only that. The screens module will hold all the screens.

// ./modules/screens.js
import { HomeScreen } from '../views/home';
import { ContactsScreen } from '../views/contacts';
import { LoadingScreen } from '../views/loading';

export const screens = {
    Home: HomeScreen,
    Contacts: ContactsScreen,
    Loading: LoadingScreen,
}

Now in App.js, I can replace 3 imports with one:

// App.js
import React from 'react';
import Icon from 'react-native-vector-icons/FontAwesome';

import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs';

import { createAppContainer } from 'react-navigation';
import { Provider as PaperProvider } from 'react-native-paper';
import { screens } from './modules/screens';

import firebase from '@react-native-firebase/app';
import '@react-native-firebase/auth';

/*
 * In the rest of the file replace:
 *
 * HomeScreen with screens.Home
 * ContactsScreen with screens.Contacts
 * LoadingScreen with screens.Loading
 *
 */

Conclusion

Now, every user of the app is authenticated. I can better segment data and keep track of usage.

Next, I’m (finally 😅) going to add storage using firestore. Till next time ✌🏾.

Powered By Swish

Comments