React Native and Firebase: Authentication

React Native is one of the most popular choices for creating cross-platform mobile apps with JavaScript and React.

Essential for many apps is registering and authenticating users, and in this tutorial I’m going to use Firebase to implement authentication in a React Native app.

Authentication allows us to secure our apps, or limit access for the non-user members. Authentication also can be used for example to limit access to a paid service or specific service. that’s just an example of how authentication can be in your app. today we will add authentication to React Native app using Firebase…

I am assuming that you’ve worked with React Native before, so I’m not going to go into details of all React Native code.

Installing react-native-firebase

The first thing we do is installing and initializing Firebase inside our app. in React Native we need to use a Firebase Container for React Native.we are going to use react-native-firebase.

If you are about to start a new React Native from scratch and you would like to use firebase you are lucky you can install react-native-firebase pre-integrated using React Native CLI.

//
npx @react-native-community/cli init --template=@react-native-firebase/template authenticationFirebase
//** source: https://invertase.io/oss/react-native-firebase/quick-start/new-project

Then just install the pod for ios by running the following command inside the root directory of your app.

cd ios && pod install

If you are having issues installing new project with firebase please refer to react-native-firebase docs

Adding react-native-firebase to an existing project

Install react-native-firebase package using yarn or npm

 yarn add @react-native-firebase/app

or:

 npm install @react-native-firebase/app

Then install pods for ios.

shell cd ios && pod install

Running the app

For iOS, there is two way to do that I personally use Xcode, it gives me a clear idea if something went wrong and the build is failed.
Xcode

Always make sure the package is running, hit yarn start to start the app.

2 - The second way to run the app on ios is running react-native run-ios command and that’s it.

Adding firebase credentials

This step requires to create a new project in the Firebase console .

After creating a new project on the dashboard page select add Firebase to iOS app this will show you the steps to add credentials to ios like below.

It consists of a few steps :

  • Downloading GoogleService-info.plist file and put it inside the ios folder within your project.
    add-firebase-ios

  • Initialize Firebase

initialize-firebase

For Android

Android has a different setup for firebase, in project setting in Firebase console select add Firebase to android.

firebase-to-android

You can put any name you like in the app name input just make sure it conforms to the firebase requirements. then click Register.

After that, you need to download google-services.jsonfile and put it within the android/app folder.

Then the next step is to initialize the Android SDK.

add-android-sdk

And one more last step is to apply the firebase plugin inside android/app/build.gradle .

apply plugin: 'com.google.gms.google-services'

if you have any issues running the steps above you always can refer to the Firebase docs or react-native-firebase website.

Now we are done with the integration, the next step is to implement Firebase functions to create users, sign In in React Native.

Adding SignIn, Login

This phase is simple, just some React and javascript code to call Firebase functions. I’m going to create a simple UI for Login and SignUp this is not necessary for this tutorial but you can skip this step.

loginComponent

I will put the full source code at the end of article *

We will use createUserWithEmailAndPassword function to sign up for a new user. I already implemented all the validation on the form we just need to call this function to create a user.

form-validation

When the user presses the Continue button, __doSignUp will be called and the code looks like below.

const __doSignUp = () => {
  if (!email) {
    setError("Email required *")
    setValid(false)
    return
  } else if (!password && password.trim() && password.length > 6) {
    setError("Weak password, minimum 5 chars")
    setValid(false)
    return
  } else if (!__isValidEmail(email)) {
    setError("Invalid Email")
    setValid(false)
    return
  }

  __doCreateUser(email, password)
}

const __doCreateUser = async (email, password) => {
  try {
    let response = await auth().createUserWithEmailAndPassword(email, password)
    if (response) {
      console.log(tag, "🍎", response)
    }
  } catch (e) {
    console.error(e.message)
  }
}

Make sure you installed @react-native-firebase/authto be able to call auth().createUserWithEmailAndPassword(email, password)

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

The function that creates a new user into Firebase looks like the following:

const __doCreateUser = async (email, password) =>{
    try {
     let response =  await auth().createUserWithEmailAndPassword(email, password);
      if(response){
        console.log(tag,"🍎",response)
      }
    } catch (e) {
      console.error(e.message);
    }

If the function throws an error make sure to enable email / password method in the authentication section in the Firebase console.

enable-email-auth

If everything went well, the data entered(email, password) is valid, an alert will show up, and if you check the Authentication section in the Firebase console you will notice that a new user is created.

signUpSuccess

Here is the source code of SignInComponent.

const SigInComponent = () => {
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")
  const [fetching, setFetching] = useState(false)
  const [error, setError] = useState("")
  const [isValid, setValid] = useState(true)
  const __doSignUp = () => {
    if (!email) {
      setError("Email required *")
      setValid(false)
      return
    } else if (!password && password.trim() && password.length > 6) {
      setError("Weak password, minimum 5 chars")
      setValid(false)
      return
    } else if (!__isValidEmail(email)) {
      setError("Invalid Email")
      setValid(false)
      return
    }

    __doCreateUser(email, password)
  }

  const __doCreateUser = async (email, password) => {
    try {
      let response = await auth().createUserWithEmailAndPassword(
        email,
        password
      )
      if (response && response.user) {
        Alert.alert("Success ✅", "Account created successfully")
      }
    } catch (e) {
      console.error(e.message)
    }
  }

  return (
    <SafeAreaView style={styles.containerStyle}>
      <View style={{ flex: 0.2 }}>
        {!!fetching && <ActivityIndicator color={blue} />}
      </View>
      <View style={styles.headerContainerStyle}>
        <Text style={styles.headerTitleStyle}> Sign Up </Text>
      </View>
      <View style={styles.formContainerStyle}>
        <TextInput
          label={"Email"}
          autoCapitalize={false}
          keyboardType="email-address"
          style={styles.textInputStyle}
          placeholder="Mail address"
          onChangeText={text => {
            setError
            setEmail(text)
          }}
          error={isValid}
        />

        <TextInput
          label={"Password"}
          secureTextEntry
          autoCapitalize={false}
          style={styles.textInputStyle}
          selectionColor={blue}
          placeholder="Password"
          error={isValid}
          onChangeText={text => setPassword(text)}
        />
      </View>
      {error ? (
        <View style={styles.errorLabelContainerStyle}>
          <Text style={styles.errorTextStyle}>{error}</Text>
        </View>
      ) : null}
      <View style={styles.signInButtonContainerStyle}>
        <TouchableHighlight
          style={styles.signInButtonStyle}
          onPress={__doSignUp}
          underlayColor={blue}
        >
          <View
            style={{
              flexDirection: "row",
              justifyContent: "space-around",
            }}
          >
            <Text style={styles.signInButtonTextStyle}>Continue</Text>
          </View>
        </TouchableHighlight>
      </View>
    </SafeAreaView>
  )
}

For LoginComponent it’s mostly the same the only thing we need to change is we use signInWithEmailAndPassword method instead.

const __doSingIn = async (email, password) => {
  try {
    let response = await auth().signInWithEmailAndPassword(email, password)
    if (response && response.user) {
      Alert.alert("Success ✅", "Authenticated successfully")
    }
  } catch (e) {
    console.error(e.message)
  }
}

And the authentication is been successfully implemented in our app 😃🙌)

Just one last thing if we have to verify if the user is already logged in we need to display something else instead of the Login, SignIn screens, for example, we display the Home screen.

We can use firebase module to verify a session, it can be imported from auth module.

import auth, { firebase } from "@react-native-firebase/auth"

 componentDidMount() {
    //  this.register("said1292@gmail.com", "123456");
    this.__isTheUserAuthenticated();
  }

  __isTheUserAuthenticated = () => {
    let user = firebase.auth().currentUser.uid;
    if (user) {
      console.log(tag,  user);
      this.setState({ authenticated: true });
    } else {
      this.setState({ authenticated: false });
    }
  };

And we can change the UI based on if the user is authenticated or not, and we can display user info by just using the same method.

firebase.auth().currentUser.email // said543@gmail.com

And to logout, you can just call await firebase.auth().signOut();

I’m sure if we integrated navigation like react-navigation will be awesome but it’s not our focus in this article so feel free to add navigation so you can just navigate to based on the user status.

Feel free to check the full source code💻on GitHub

Thanks for reading

#react-native #firebase #mobile-apps

React Native and Firebase: Authentication
3.40 GEEK