How To Build A Chat App With React Native

in #art7 years ago

Chat Screen

That’s all we need to do in our Main.js, you can open the Chat.js and start adding some chat stuff!

components/Chat.js

import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
class Chat extends Component {
render() {
return <View />;
}
}
const styles = StyleSheet.create({});
export default Chat;

To get started make sure your Chat.js looks like this. Let’s setup the chat component.

import React from 'react';
// 1.
import { GiftedChat } from 'react-native-gifted-chat';
class Chat extends React.Component {
 // 2.
static navigationOptions = ({ navigation }) => ({
title: (navigation.state.params || {}).name || 'Chat!',
});
 // 3.
state = {
messages: [],
};

render() {

 // 4.
return (
<GiftedChat
messages={this.state.messages}
/>
);
}
}
export default Chat;
  1. Import GiftedChat from ‘react-native-gifted-chat’ This is the component that we will use to do most of the heavy lifting.
  2. navigationOptions is used to configure how the navigation components (Header) look and act. We are passing an object with a title property that will set the title to either the state.params.name or a default value of Chat!
  3. Create the component state and give it a messages prop then assign it to an array.
  4. Replace the View with the GiftedChat component and give it our state.messages to render.

Database

This is a pretty good start, we need a way to get messages and determine which ones came from us. Now we will add a listener that gets called whenever a message is sent or received.

Let’s go to Fire.js to set this up!

/Fire.js

class Fire {}
Fire.shared = new Fire();
export default Fire;

We should just have a basic class with a shared instance setup, let’s setup a Firebase app.

// 1.
import firebase from 'firebase';
class Fire {
constructor() {
this.init();
}
 // 2.
init = () =>
firebase.initializeApp({
apiKey: 'AIzaSyDLgW8QG1qO8O5WZLC1U8WaqCr5-CvEVmo',
authDomain: 'chatter-b85d7.firebaseapp.com',
databaseURL: 'https://chatter-b85d7.firebaseio.com',
projectId: 'chatter-b85d7',
storageBucket: '',
messagingSenderId: '861166145757',
});
}
  1. Import firebase, we will use this to access our database
  2. Initialize our Firebase app using the keys we get in our app

Here is an example of the creds

In order to write and read from our database we need to be logged in, to do this we will get our current authentication, if it doesn’t exist then we want to sign in anonymously.

class Fire {
constructor() {
this.init();
 // 1.
this.observeAuth();
}
 // 2.
observeAuth = () =>
firebase.auth().onAuthStateChanged(this.onAuthStateChanged);
 // 3.
onAuthStateChanged = user => {
if (!user) {
try {
// 4.
firebase.auth().signInAnonymously();
} catch ({ message }) {
alert(message);
}
}
};
}
  1. After initializing, call our observeAuth function
  2. we want to get our auth, if we were signed in before then this will return a user, if we weren’t then this will be null.
  3. onAuthStateChanged gets called as soon as firebase finds our auth.
  4. if we weren’t signed in then sign in anonymously, if this fails then we will pop an alert with an error message.

Now we need a way to subscribe to messages, after onAuthStateChanged

// 1.
get ref() {
return firebase.database().ref('messages');
}
// 2.
on = callback =>
this.ref
.limitToLast(20)
.on('child_added', snapshot => callback(this.parse(snapshot)));
// 3.
parse = snapshot => {
}
// 4.
off() {
this.ref.off();
}
  1. Create a reference to a location in our database where the messages will be saved, in our case it’s /messages
  2. Make a method with a callback prop that calls our messages ref and get’s the last 20 messages, then whenever a new message comes in we will get that as well. When we get a message we want to send it a function to parse.
  3. Create the parse method, we will add more here later
  4. Add a function to unsubscribe to the database

Ok now we can get messages, we need to format them correctly for GiftedChat, to do this we will reduce (change the shape) the snapshot (data returned from firebase) in the parse method.

parse = snapshot => {
 // 1.
const { timestamp: numberStamp, text, user } = snapshot.val();
const { key: _id } = snapshot;
 // 2.
const timestamp = new Date(numberStamp);
 // 3.
const message = {
_id,
timestamp,
text,
user,
};
return message;
};
  1. Deconstruct the snapshot.val(), calling snapshot.val() will return the value or object associated with the snapshot
  2. Let’s convert the timestamp that was saved, to a js Date.
  3. Finally we will create an object that GiftedChat is familiar with, then return it, _id is the unique key for the message, text, user, and timestamp are exactly what you might think.

We now need a way to send messages

// 1.
get uid() {
return (firebase.auth().currentUser || {}).uid;
}
// 2.
get timestamp() {
return firebase.database.ServerValue.TIMESTAMP;
}

// 3.
send = messages => {
for (let i = 0; i < messages.length; i++) {
const { text, user } = messages[i];

 // 4.
const message = {
text,
user,
timestamp: this.timestamp,
};
this.append(message);
}
};
// 5.
append = message => this.ref.push(message);
  1. Create a helper for getting the user’s uid
  2. Get the accurate timestamp for saving messages
  3. Make a send function that accepts an array of messages, then loop through the messages
  4. Create a shape that if good for firebase and save it to our server
  5. The append function will save the message object with a unique ID

That’s it for the backend, now we can go back to the Chat.js screen and connect everything!

At the bottom of the component add subscribers and unsubscribers:

components/Chat.js

// 1.
componentDidMount() {
Fire.shared.on(message =>
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, message),
}))
);
}
// 2.
componentWillUnmount() {
Fire.shared.off();
}
  1. When the component is added to the screen, we want to start looking for messages. Call the Fire.shared.on method and pass in a callback. We want our callback to get messages then add them to our current messages.
  2. When the component leaves the screen we want to unsubscribe from the database.

Next we need a simple reference to our user so GiftedChat knows which side of the screen to put our chat bubbles on…

get user() {
 // Return our name and our UID for GiftedChat to parse
return {
name: this.props.navigation.state.params.name,
_id: Fire.shared.uid,
};
}

Finally we need to give GiftedChat a reference to our user and the onSend method from Fire

render() {
return (
<GiftedChat
messages={this.state.messages}
onSend={Fire.shared.send}
user={this.user}
/>
);
}

And that’s it! Now when you run the build you should be able to join your group and start saving messages to the database!!!


Also your header should have text, my phone is on the bed behind me and I don’t want to get up and grab it, so enjoy these screenshots instead 💙😜

Links

The full project: https://snack.expo.io/@bacon/firebase-basic-chat

Actively avoid my twitter:

And show people the stuff you made on our forums! ⭐️💙



Posted from my blog with SteemPress : http://selfscroll.com/how-to-build-a-chat-app-with-react-native/

Sort:  

Warning! This user is on my black list, likely as a known plagiarist, spammer or ID thief. Please be cautious with this post!
If you believe this is an error, please chat with us in the #cheetah-appeals channel in our discord.

This user is on the @buildawhale blacklist for one or more of the following reasons:

  • Spam
  • Plagiarism
  • Scam or Fraud