Skip to content

Instantly share code, notes, and snippets.

@Luisquii
Last active January 18, 2020 05:40
Show Gist options
  • Save Luisquii/c5361fa15796c456400cf3ad66effd6e to your computer and use it in GitHub Desktop.
Save Luisquii/c5361fa15796c456400cf3ad66effd6e to your computer and use it in GitHub Desktop.
React-native full login and sign up system with firebase

React-native full login and sign up system with firebase

You need to create a react-native app with firebase (obviously have a firebase project) following the next guide.

Then you need to install react-navigation:

npm install react-navigation
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context

Install react-navigation-stack:

npm install react-navigation-stack @react-native-community/masked-view

Optional - Install react-native-vector-icons (These example uses it)

This example has 5 files:

  • App.js -> where the logic for screen naviation is
  • Loading.js -> Check if the user has an active session. If true navigate to Home screen, if false navigate to Sign Up screen
  • SignUp.js -> Register new users.
  • Login.js -> For user to login.
  • Home.js -> Simple Home and a logout button that returns to Login
App.js
import React, { Component } from "react";
import { Platform, StyleSheet, Text, View } from "react-native";

//import firebase from "@react-native-firebase/app";
import { createAppContainer, createSwitchNavigator } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";

// TODO(you): import any additional firebase services that you require for your app, e.g for auth:
//    1) install the npm package: `yarn add @react-native-firebase/auth@alpha` - you do not need to
//       run linking commands - this happens automatically at build time now
//    2) rebuild your app via `yarn run run:android` or `yarn run run:ios`
//    3) import the package here in your JavaScript code: `import '@react-native-firebase/auth';`
//    4) The Firebase Auth service is now available to use here: `firebase.auth().currentUser`

// import the different screens
import Loading from "./src/screens/components/Loading";
import SignUp from "./src/screens/containers/SignUp";
import Login from "./src/screens/containers/Login";
import Home from "./src/screens/components/Home";

//App navigation
const AppNavigator = createStackNavigator({
 Home: {
   screen: Home,
   navigationOptions: {
     title: "Welcome"
   }
 }
});

//User auth
const AuthStackNavigator = createSwitchNavigator(
 {
   Loading: {
     screen: Loading,
     navigationOptions: {
       title: "Loading"
     }
   },
   SignUp: {
     screen: SignUp,
     navigationOptions: {
       title: "Sign Up"
     }
   },
   Login: {
     screen: Login,
     navigationOptions: {
       title: "Login"
     }
   }
 },
 {
   initialRouteName: "Loading"
 }
);

export default createAppContainer(
 createSwitchNavigator(
   {
     Loading: AuthStackNavigator,
     SignUp: AuthStackNavigator,
     Login: AuthStackNavigator,
     Home: AppNavigator
   },
   {
     initialRouteName: "Loading"
   }
 )
);

Loading.js
  // Loading.js
import React from "react";
import { View, Text, ActivityIndicator, StyleSheet } from "react-native";

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

export default class Loading extends React.Component {
  componentDidMount() {
    auth().onAuthStateChanged(user => {
      this.props.navigation.navigate(user ? "Home" : "SignUp");
    });
  }

  render() {
    return (
      <View style={styles.container}>
        <Text>Loading</Text>
        <ActivityIndicator size="large" />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  }
});
SignUp.js
import React, { Component } from "react";
import { StyleSheet, Text, TextInput, View, Button } from "react-native";

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

export default class SignUp extends Component {
  state = {
    email: "",
    password: "",
    errorMessage: null
  };

  handleSignUp = () => {
    auth()
      .createUserWithEmailAndPassword(this.state.email, this.state.password)
      .then(() => this.props.navigation.navigate("Home"))
      .catch(error => this.setState({ errorMessage: error.message }));
  };

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.title}>Sign Up</Text>

        {this.state.errorMessage && (
          <Text style={{ color: "red" }}>{this.state.errorMessage}</Text>
        )}
        <TextInput
          placeholder="Email"
          autoCapitalize="none"
          style={styles.textInput}
          onChangeText={email => this.setState({ email })}
          value={this.state.email}
        />
        <TextInput
          secureTextEntry
          placeholder="Password"
          autoCapitalize="none"
          style={styles.textInput}
          onChangeText={password => this.setState({ password })}
          value={this.state.password}
        />
        <Button color="#ffa31a" title="Sign Up" onPress={this.handleSignUp} />
        <View>
          <Text
            onPress={() => this.props.navigation.navigate("Login")}
            style={{ fontSize: 16 }}
          >
            Already have an account?
            <Text style={{ color: "#00b300", fontSize: 18 }}> Login</Text>
          </Text>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  },
  title: {
    color: "#ffa31a",
    fontSize: 30,
    fontWeight: "bold"
  },
  textInput: {
    height: 50,
    fontSize: 20,
    width: "90%",
    borderColor: "#9b9b9b",
    borderBottomWidth: 1,
    marginTop: 8,
    marginVertical: 15
  }
});
Login.js
// Login.js
import React from "react";
import { StyleSheet, Text, TextInput, View, Button } from "react-native";

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

export default class Login extends React.Component {
  state = { email: "", password: "", errorMessage: null };

  handleLogin = () => {
    const { email, password } = this.state;

    auth()
      .signInWithEmailAndPassword(email, password)
      .then(() => this.props.navigation.navigate("Home"))
      .catch(error => this.setState({ errorMessage: error.message }));
  };

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.title}>Login</Text>
        {this.state.errorMessage && (
          <Text style={{ color: "red" }}>{this.state.errorMessage}</Text>
        )}
        <TextInput
          style={styles.textInput}
          autoCapitalize="none"
          placeholder="Email"
          onChangeText={email => this.setState({ email })}
          value={this.state.email}
        />
        <TextInput
          secureTextEntry
          style={styles.textInput}
          autoCapitalize="none"
          placeholder="Password"
          onChangeText={password => this.setState({ password })}
          value={this.state.password}
        />
        <Button color="#ffa31a" title="Login" onPress={this.handleLogin} />
        <View>
          <Text
            onPress={() => this.props.navigation.navigate("SignUp")}
            style={{ fontSize: 16 }}
          >
            Don't have an account?
            <Text style={{ color: "#00b300", fontSize: 18 }}> Sign Up</Text>
          </Text>
        </View>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  },
  title: {
    color: "#ffa31a",
    fontSize: 30,
    fontWeight: "bold"
  },
  textInput: {
    height: 50,
    fontSize: 20,
    width: "90%",
    borderColor: "#9b9b9b",
    borderBottomWidth: 1,
    marginTop: 8,
    marginVertical: 15
  }
});

Home.js
//Home

import React, { Component } from "react";
import { StyleSheet, Platform, Image, Text, View, Alert } from "react-native";

import firebase from "@react-native-firebase/app";
import auth from "@react-native-firebase/auth";
import Icon from "react-native-vector-icons/FontAwesome";

export default class Home extends Component {
  state = { currentUser: null };

  handleSignOut = () => {
    auth()
      .signOut()
      .then(function() {
        // Sign-out successful.
        () => this.props.navigation.navigate("Login");
      })
      .catch(function(error) {
        console.log("Error" + error.toString());
      });
  };

  componentDidMount() {
    const { currentUser } = auth();
    this.setState({ currentUser });
  }

  render() {
    const { currentUser } = this.state;

    return (
      <View style={styles.container}>
        <Text>Hi {currentUser && currentUser.email}</Text>
        <View>
          <Icon.Button
            name="sign-out"
            color="#000000"
            backgroundColor="white"
            onPress={this.handleSignOut}
          />
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  }
});

Reference:

https://medium.com/react-native-training/react-native-firebase-authentication-7652e1d2c8a2

https://medium.com/@eng.sohaddader/start-with-react-native-firebase-authentication-and-realtime-database-services-466359d577c6

https://snack.expo.io/?platform=android&name=Auth%20Flow&dependencies=react-navigation%40%5E4.0.10%2Creact-navigation-tabs%40%5E2.5.6%2Creact-navigation-stack%40%5E1.10.3%2Creact-navigation-drawer%40%5E2.3.3&sourceUrl=https%3A%2F%2Freactnavigation.org%2Fexamples%2F4.x%2Fauth-flow.js @Luisquii

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment