[DIY] Create an AirBnB Clone with React Native - Part IV: Login Error Notifications

Written by krissanawat101 | Published 2019/09/20
Tech Story Tags: react-native-development | react-native | making-an-airbnb-clone | developing-on-react-native | latest-tech-stories | react-tutorial | login-error-troubleshooting | tutorial | web-monetization

TLDR This tutorial is the fourth chapter of our implementation of an AirBnB clone in React Native. In previous chapters, we’ve successfully implemented email authentication with Firebase. We’re going to create an alert bar at the bottom of the screen and change the background color that shows the Firebase validation notification. We're going to use the FontAwesome icon bundle and wrap the icon around TouchableOpacity in order to make the icon clickable. Then we need to add a close button to hide the notification.via the TL;DR App

This tutorial is the fourth chapter of our implementation of an AirBnB clone in React Native. In previous chapters, we’ve successfully implemented email authentication with Firebase. In case you need to get caught up, here are links to parts 1–3:
In part 4, we’re going to continue from where we left off, implementing a notification feature for the authentication process. In summary, we’re going to create an alert bar at the bottom and change the background color that shows the Firebase validation notification.
So, let’s get started!
Create a notification component
First, we’re going to create a simple component named Notification inthe Notification.js file. Here, we need to create a simple class named Notification that extends to the component module of React. For now, we’re just going to render text using a Text component wrapped inside the View component, as shown in the code snippet below:
<View style={styles.nextButtonWrapper}>
            <NextArrowButton handleLogin={this.Login} />
          </View>
        </View>
        <View>
          <Notification />
        </View>
Next, we’re going to import our Notification component into our Login component in the Login.js file, as shown in the code snippet below:
import Notification from "../components/Notification";
Then we need to initialize or render our Notification component after the Login button initialized in the NextArrowButton component, as shown in the code snippet below:
<View style={styles.nextButtonWrapper}>
            <NextArrowButton handleLogin={this.Login} />
          </View>
        </View>
        <View>
          <Notification />
        </View>
As a result, you’ll get the text in the Notification component displayed at the bottom of the screen, as shown in the emulator screenshot below:
Send a message from parent to child component
In this step, we’re going to work on the Notification component and send props from the parent component (i.e. the Login component) and receive the props in child component (i.e. the Notification component). Here, we’re going to send error message from the Login component to the Notification component as props.
For that, we need to add two Text components in the Notification component for title and message, in which we receive the data as props from the Login component. The code to handle this is shown in the snippet below:
export default class Notification extends Component {
  render() {
    const { title, message } = this.props;
    return (
      <View>
        <Text>{title}</Text>
        <Text>{message}</Text>
      </View>
    );
  }
}
Then, we need to send data (i.e. props title and message) from the parent component (i.e. Login component), as shown in the code snippet below:
<Notification title="Error" message="some thing went wrong" />
As a result, we get the following screen where title and message from the Notification component are imported to the Login component and are displayed at the bottom of the screen:

Styling the Notification component

Here, we’re going to add some style to our Notification component in order to make it look more appealing. We’re going to use the Stylesheet component imported from the react-native package to define the styles required. Then, we need to bind those styles to our component, which are being rendered as shown in the snippet below:
export default class Notification extends Component {
  render() {
    const { title, message } = this.props;
    return (
      <View>
        <View style={styles.notificationContent}>
          <Text style={styles.title}>{title}</Text>
          <Text style={styles.messsage}>{message}</Text>
        </View>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  notificationContent: {
    flexDirection: "row",
    flexWrap: "wrap",
    alignItems: "flex-start"
  },
  title: {
    color: colors.darkOrange
  }
})
We can see that the styles are bound to the View and Text components. And the result of adding styles is shown in the emulator screenshot below:
The error text and the message in the above screenshot still appear out of place at the bottom of the screen. So we need to add more style to the container in order to position the Notification component correctly in the Login screen.
For that, we’re going to wrap the outermost View component with another View component and bind it with the wrapper style, as shown in the code below:
export default class Notification extends Component {
  render() {
    const { title, message } = this.props;
    return (
      <View style={styles.wrapper}>
        <View style={styles.notificationContent}>
          <Text style={styles.title}>{title}</Text>
          <Text style={styles.messsage}>{message}</Text>
        </View>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  wrapper: {
    backgroundColor: "white",
    height: 60,
    width: "100%",
    padding: 10
  },
  notificationContent: {
    flexDirection: "row",
    flexWrap: "wrap",
    alignItems: "flex-start"
  },
  title: {
    color: colors.darkOrange,
    marginRight: 5,
    fontSize: 14,
    marginBottom: 2
  },
  messsage: {
    marginBottom: 2,
    fontSize: 14
  }
});
As a result, we get a more refined look at our Notification component at the bottom of the Login screen, as shown below:

Adding a close button

Next, we’re going to add a close button in order to hide the notification. For that, we’ll use the FontAwesome icon bundle from the react-native-vector icons package.
Here we’re going to use the FontAwesome icon bundle and wrap the icon around TouchableOpacity in order to make the icon clickable.
First, we need to import the FontAwesome icon bundle from the react-native-vector-icons package into the Icon component using the following piece of code:
import Icon from "react-native-vector-icons/FontAwesome";
Then we need to add the Icon component to the notification container wrapped by TouchableOpacity, as shown in the code snippet below:
<View style={styles.wrapper}>
        <View style={styles.notificationContent}>
          <Text style={styles.title}>{title}</Text>
          <Text style={styles.messsage}>{message}</Text>
        </View>
        <TouchableOpacity
          style={styles.closeButton}
          onPress={this.closeNotification}
        >
          <Icon name="times" size={20} color={colors.lightGray} />
        </TouchableOpacity>
      </View>
Here, we can see that the Icon component with the icon named times is added with the color prop as light gray. Then we need to add style to the TouchableOpacity component to make it stick right in the Notification component. The style we’re adding is closeButton, which is provided in the code snippet below:

 closeButton: {
    position: "absolute",
    right: 10,
    top: 10
  }
Last but not least, we need to add a blank function called closeNotification to handle the onPress event from the TouchableOpacity component, as shown in the code snippet below:
closeNotification = () => {
    alert("close notification");
  };
The function consists of an alert method in order to check if the function triggers properly when the close button is pressed. The result of adding the close ‘x’ button is shown in the emulator screenshot below:

Handling the close notification

Here we need to handle the close notification event from the parent component (Login). So we need to create a function in the Login component, which is triggered when we press the close notification button in the Notification component.
First, we need to create a function in the Login component named handleCloseNotification, which is triggered when we press the close button in the Notification component. The function implementation is given below:
handleCloseNotification = () => {
    alert("close Notification");
  };
Then, in the Notification component imported in the Login component, we need to set a prop function to trigger the handleCloseNotification function:
 <Notification
     handleCloseNotification={this.handleCloseNotification}
     title="Error"
     message="Those credentials don't look right please try agiain"
/>
Now, in the Notification component, we receive the handleCloseNotification event from the parent component using props and trigger the function inside the closeNotification function using the code in the following snippet:
closeNotification = () => {
    this.props.handleCloseNotification();
  };
Now we can see that an alert is triggered by the parent component. When we press the close button, the closeNotification function is triggered in the Notification component, which triggers the handleCloseNotification prop and sends the trigger message to the handleCloseNotification function in the Login component. As a result, we see the following result in the emulator screen:

Hiding or showing the notification

Here we’re going to implement the hiding and showing of the error notification. In order to control the notification’s appearance, we’re going to use simple props that send state from the Login component to the Notification component.
In Login.js, i.e. our Login component, we need to create a state to handle the notification state. The state variable to handle the notification state is formValid, as coded in the snippet below:
constructor() {
    super();

    this.state = {
      user: null,
      email: "",
      password: "",
      formValid: true,
      error: ""
    };
  }
Then we need to add the state to the render function to send it to the Notification component, as shown in the code snippet below:
render() {
    const { formValid } = this.state;
    const showNotification = formValid ? false : true;
In the code snippet above, we’ve created a new variable named showNotification, which sets its value as either true or false depending upon the formValid state. Then, we need to send the showNotification variable as a prop to the Notification component, as shown in the code snippet below:

  <Notification
      showNotification={showNotification}
      handleCloseNotification={this.handleCloseNotification}
      title="Error"
      message="Those credentials don't look right please try agiain"
  />
Next we need to handle the state on the Notification container by adding marginBottom to make the view disappear or hide from the visible area, depending on the state value that’s received from the Login component.
In order to do that, first, we need to receive the showNotification prop from the Login component, and then set the value of the bottom variable to 80 or 0, depending on the showNotification prop value.
Then, we need to bind the bottom variable value to the marginBottom style integrated into the outermost view of the Notification component, as shown below:
render() {
    const { title, message, showNotification } = this.props;
    const bottom = showNotification ? -80 : 0;
    return (
      <View style={[{ marginBottom: bottom }, styles.wrapper]}>
        <View style={styles.notificationContent}>
          <Text style={styles.title}>{title}</Text>
          <Text style={styles.messsage}>{message}</Text>
        </View>
Now we can hide or show the notification container from the parent component.

Using the close button to hide notification

Now we can control the close button manually. But in order to actually use the close button, we need to add some function to handle the showNotification state.
Let’s first test the close button functionality by refreshing the emulator and pressing the close button. We can see the result in the emulator simulation below:
Finally, we can close the notification.

Bringing it all together

At this point, we’ve implemented a notification bar that we can show or hide as we’d like.
Next, we need to use a response from Firebase control in place of the hardcoded error message. So when we get an error from Firebase control, we need to show that error message in the Notification bar at the bottom. The code to implement this is shown in the code snippet below:
Login = () => {
    firebase
      .auth()
      .signInWithEmailAndPassword(this.state.email, this.state.password)
      .then(user => {
        this.setState({ user });
        console.log(user);
      })
      .catch(error =>
        this.setState({ error: error.message, formValid: false })
      );
  };
Then we need to assign the error state to the message prop of the Notification element in the Login component in order to send it to the Notification:
<Notification
       showNotification={showNotification}
       handleCloseNotification={this.handleCloseNotification}
       title="Error"
       message={this.state.error}
/>
And to handle the close function, we switch the trigger state to make the notification bar hide by default.
Now we can see the result in the emulator simulation below:
As we can see, the notification error message works perfectly.

Adding animation and changing the background color

Lastly, we’re going to add an animation to make the notification component slide in and slide out. And then, we’re going to toggle the background color of the Login screen when the notification is triggered.

Changing the background color

Here, when the error notification shows up, we want to change the background color in the Login screen. For that, we use the formValid state to toggle between two main colors, i.e. dark green and dark orange, and set it up to the main wrapper, i.e. the KeyboardAvoidingView component in the Login component. The code for this is provided in the snippet below:
render() {
    const { formValid } = this.state;
    const showNotification = formValid ? false : true;
    const bgColor = formValid ? colors.green01 : colors.darkOrange;
    return (
      <KeyboardAvoidingView
        style={[{ backgroundColor: bgColor }, styles.wrapper]}
        behavior="padding"
      >
Now let’s test to see if it works:
As we can see, the screen color changes successfully in the above simulation. Now let’s add our animation.

Animation: slide in and slide out

Here we want to add a slide in and slide out animation to the Notification container.
First, to implement animation, we need to import Animate and Easing components from the react-native package in the Notification component:
import {
  View,
  Text,
  TouchableOpacity,
  StyleSheet,
  Animated,
  Easing
} from "react-native";
Then we need to initialize the Animate.value method to the positionValue variable. After that, we need to create a function named animateNotification and initialize an animation timing method, Animated.timing, which helps to define the animation styles. For more information on animation properties, you can check the official documentation here.
The first parameter in the timing function is the positionValue, and the second parameter is the animation config option, shown in the code snippet below:
import {
	  View,
	  Text,
	  TouchableOpacity,
	  StyleSheet,
	  Animated,
	  Easing
	} from "react-native";
Now in the Notification component, we need to replace the bottom variable values with the initialized animation value using the showNotification function to toggle between show and hide.
Then we need to replace our normal View component with the Animation View component. Finally, we need to replace the marginBottom value with the Animated.Value that we defined in the constructor.
export default class Notification extends Component {
  constructor(props) {
    super(props);
    this.positionValue = new Animated.Value(-80);
  }
  animateNotification = value => {
    Animated.timing(this.positionValue, {
      toValue: value,
      duration: 300,
      velocity: 3,
      tension: 2,
      friction: 8,
      easing: Easing.easeOutBack
    }).start();
  };
Now, let’s try it out:
As we can see, the slide in and slide out animation works perfectly.
This completes our tutorial of implementing the authentication notification feature in our AirBnB clone app using React Native.

Conclusion

In this tutorial, we learned how to implement a notification bar during user authentication.
We also learned how to pass data between parent and child components in React Native. In the implementation of the notification bar, we got a step-by-step guide for displaying an error message from the Firebase server. Lastly, we learned how to control the styles dynamically with the state variable and how to add animations.
All the code for this tutorial is available in this GitHub repo. In the next chapter, we’re going to continue to implement our AirBnB clone app with a Firebase Email Register Screen.

Disclosure

This post includes affiliate links; I may receive compensation if you purchase products or services from the different links provided in this article.

Resource


Written by krissanawat101 | React native Developer ,Coffee addict
Published by HackerNoon on 2019/09/20