Membuat Aplikasi Chatting React Native

Membuat Aplikasi Chatting React Native

Belajar bahasa pemrograman tak lengkap rasanya jika kita belum berinteraksi dengan sebuah case sederhana untuk membantu kita memahami cara kerja dari sebuah bahasa pemrograman, meskipun sebelumnya kita telah belajar dengan berbagai macam case, namun pada case kali ini kita akan berinteraksi dengan database menggunakan Firebase dengan contoh kasus yakni membuat aplikasi chatting yang kita beri nama Whatsapp Clone. Adapun artikel ini masih merupakan lanjutan dari artikel sebelumnya yang membahas tentang React Native Navigation, maka dari itu kita masih akan menggunakan source code yang telah kita buat sebelumnya.

Baca Juga: React Native Navigation

Apa itu Firebase?

Firebase adalah sebuah platform yang memberikan anda beberapa pilihan layanan meliputi: react-time database, authentication, cloud storage yang dapat digunakan untuk berinteraksi dengan aplikasi anda. Selain itu, Firebase menawarkan dynamic links seperti analystic, adwords, admobs, crash reporting, notifications, testing dan lain sebagainya. Kamu dapat memeriksa semua opsi ini didalam console Firebase setelah anda membuat akun Firebase.

Tahap Persiapan

Sebelum kita bergelut dengan React Native, tahap awal yang akan kita lakukan terlebih dahulu adalah mempersiapkan service Firebase.

  1. Buat akun Firebase menggunakan akun Google kamu : https://firebase.google.com

  2. Setelah itu kamu dapat meng-klik GET STARTED atau GO TO CONSOLE, dan kamu akan diarahkan ke dalam Firebase console, dimana kamu dapat membuat konfigurasi Firebase.

  3. Klik Add Project untuk membuat service baru yang akan digunakan nantinya, kemudian masukkan informasi yang diminta pada form yang disediakan (Baca: isi project name dan Country or Region)

  4. Setelah itu kamu akan diarahkan kedalam console dashboard yang tampak seperti berikut:

Pada dashboard di atas terdapat banyak sekali opsi yang dapat digunakan sebagaimana yang telah disinggung sebelumnya. Kamu dapat mengecek setiap opsi yang terdapat di-dashboard tersebut dan membaca tentangnya. Namun pada artikel kali ini, kita tidak akan membahas secara keseluruhan karena kita hanya akan berfokus pada opsi yang akan menunjang pembelajaran kita dengan case membuat aplikasi chatting.

Membuat Real-time Database

Dalam artikel sebelumnya yang membahas tentang React Native Navigation, kita telah membuat sebuah screen untuk chatting dan kemudian kita akan melanjutkannya dengan menggunakan Firebase real-time database agar chat yang akan ditampilkan bersifat dinamis. Namun, sebelum kita berinteraksi dengan source code React Native, masih terdapat tahapan yang harus diselesaikan terlebih dahulu, yakni membuat database.

Pada menu yang terdapat didalam console Firebase, pilih Database dan kemudian akan menampilkan halaman Realtime Database dengan database yang masih kosong. Karena Firebase real-time database menyimpan data kedalam JSON format, maka untuk mempermudah memasukkan data dummy berikut struktur yang akan digunakan, kita akan menggunakan file json. Buat data.json kemudian masukkan baris berikut:

{
  "messages" : [ {
    "incoming" : true,
    "message" : "Halo Nuge"
  }, {
    "incoming" : false,
    "message" : "Halo Juga"
  }, {
    "incoming" : true,
    "message" : "Ngumpul yuk, udah lama nih nggak bareng"
  }, {
    "incoming" : false,
    "message" : "Males ah, karena ngumpul itu hanya sebuah mitos yang akan angker pada waktunya"
  } ]
}

Masih dalam halaman Real Time Database, klik icon titik tiga pada sudut kanan kemudian klik Import JSON lalu pilih file JSON yang telah dibuat.

Setelah proses Import selesai, maka halaman database dalam console Firebase akan tampak seperti berikut ini:

Karena kita belum memasuki pembelajaran tentang authentication, maka RULES akan kita set agar dapat diakses secara public tanpa melalui proses otentikasi dan untuk melakukannya, pilih tab RULES kemudian masukkan code berikut:

{
  "rules": {
    ".read": "true",
    ".write": "true"
  }
}

Kolaborasi React Native & Firebase

Tahap persiapan dan segala hal yang dibutuhkan untuk dikonfigurasi didalam Firebase telah selesai, maka tahap selanjutnya adalah membuat konfigurasi agar dapat menggunakan Firebase dengan React Native:

  1. Kembali ke Dashboard dengan meng-klik tombol Overview dan pilih Add Firebase to Your Web App

  2. Setelah itu kamu akan mendapatkan code konfigurasi dari Firebase. Di dalam folder src, buat folder services yang didalam terdapat file firebase.js (path lengkapnya: src/services/firebase.js), kemudian masukkan code berikut:

    import * as firebase from "firebase";
    ​
    export const initialize = () => firebase.initializeApp({
        apiKey: "AIzaSyAsq5_Bz7k0NvHwgkujU5rsFdltIiKx42s",
        authDomain: "dwauth-a7b5e.firebaseapp.com",
        databaseURL: "https://dwauth-a7b5e.firebaseio.com",
        projectId: "dwauth-a7b5e",
        storageBucket: "dwauth-a7b5e.appspot.com",
        messagingSenderId: "913864115277"
    });

    Note: ganti code konfigurasi diatas (baca: mulai dari apiKey sampai messagingSenderId) dengan code konfigurasi yang kamu dapatkan dari Firebase console.

  3. Karena kita meng-import module firebase, maka install module tersebut dengan command:

    npm install firebase --save
  4. Masih didalam folder services, buat file api.js kemudian masukkan code berikut yang berfungsi untuk meng-export function initialize dari Firebase dengan nama initApi.

    import { initialize } from './firebase';
    export const initApi = () => initialize();
  5. Kemudian buka file App.js pada root directory kemudian lakukan perubahan pada file tersebut menjadi seperti ini:

    import React from 'react';
    import { StackNavigator } from 'react-navigation';
    import routes from './src/config/routes';
    import { initApi } from './src/services/api';
    ​
    const AppNavigator = StackNavigator(routes);
    ​
    export default class extends React.Component {
      componentWillMount(){
        initApi();
      }
    ​
      render() {
        return (
          <AppNavigator />
        );
      }
    }

    Penjelasan: Karena function initialize telah di-export dengan nama initApi maka pada code diatas kita meng-import initApi dari src/service/api.js kemudian me-load-nya kedalam componentWillMount lifecycle hook yang akan dijalankan sebelum component di-load.

Karena aplikasi chatting bersifat real-time, maka kita perlu membuat sebuah fitur yang berfungsi untuk meng-update state setiap kali terjadi perubahan database.

  1. Buka file firebase.js kemudian tambahkan code berikut:

    export const setListener = (endpoint, updaterFn) => {
        firebase.database().ref(endpoint).on('value', updaterFn);
        return () => firebase.database().ref(endpoint).off();
    }

    Penjelasan: Function diatas akan melakukan dua hal, pertama, setelah mem-passing endpoint dan updaterFn sebagai argumen, kita akan mengakses data kedalam database menggunakan firebase.database().ref(endpoint). Kemudian dengan firebase.database().ref(endpoint).off() yang digunakan untuk menghapus attached listener.

  2. Buka file api.js, kemudian kita akan membuat function getMessages dan menggunakan setListener yang telah dibuat sebelumnya:

    export const getMessages = (updaterFn) => setListener('messages', updaterFn);

    Note: Jangan lupa untuk memperbaharui bagian import dari Firebase mejadi:

    import { setListener, initialize } from './firebase';
  3. Kemudian import function getMessages dari src/services/api ke dalam src/screens/ChatScreen.js:

    import { getMessages } from '../services/api';

    Masih di dalam ChatScreen.js, tambahkan code berikut:

    componentDidMount() {
        this.unsubscribeGetMessages = getMessages((snapshot) => {
            this.setState({
                messages: Object.values(snapshot.val())
            })
        })
    }
    componentWillUnmount() {
        this.unsubscribeGetMessages();
    }

    Penjelasan: Kita menggunakan Object.values dalam Firebase snapshot.val() karena FlatList menggunakan array dan Firebase menghasilkan object. Ketika getMessages dipanggil maka setListener akan me-return sebuah function untuk menghapus listener menggunakan firebase.database().ref(endpoint).off(). Kemudian kita dapat menyimpan hasil dari getMessages ke dalam this.unsubscribeGetMessages yang kemudian dapat digunakan kembali ke dalam componentWillUnmount lifecycle hook yang akan dijalankan kembali sebelum component unmounted dan destroyed.

  4. Masih bekerja menggunakan file ChatScreen.js, pada render method ubah menjadi seperti:

    render() {
         return (
             <ImageBackground
        style={[ styles.container, styles.backgroundImage ]}
        source={require('../assets/img/background.png')}>
        <FlatList
            style={styles.container}
            data={this.state.messages}
            renderItem={Message}
            keyExtractor={(item, index) => (`message-${index}`)}
        />
        <Compose submit={postMessage} />
    </ImageBackground>
         )
     }

    Penjelasan:

    Karena kita memanggil component ImageBackground & FlatList maka import terlebih dahulu:

    import { ImageBackground, StyleSheet, FlatList } from 'react-native';

    Adapun style yang digunakan dari kedua component diatas harus didefinisikan juga, maka tambahkan code berikut:

    const styles = StyleSheet.create({
        container: {
            flex: 1,
            backgroundColor: 'transparent'
        },
        listItem: {
            width: '70%',
            margin: 10,
            padding: 10,
            backgroundColor: 'white',
            borderColor: '#979797',
            borderStyle: 'solid',
            borderWidth: 1,
            borderRadius: 10
        },
        incomingMessage: {
            alignSelf: 'flex-end',
            backgroundColor: '#E1FFC7'
        } 
    })

    Pada component ImageBackground kita menggunakan props source yang akan me-load gambar, maka gambarnya dapat kamu download disini : github. Component FlatList, pada props data menggunakan state messages: this.state.messages, maka tambahkan code berikut diluar render method:

    state = {
        messages: []
    }

    Sedangkan props renderItem mengakses component Message, maka pada folder src buat folder components yang didalamnya terdapat file Message.js, lalu masukkan code berikut:

    import React from 'react';
    import { View, StyleSheet, Text } from 'react-native'
    ​
    const Message = ({ item }) => (
      <View style={[
          styles.message, item.incoming &&
          styles.incomingMessage
        ]}>
        <Text>{item.message}</Text>
      </View>
    )
    ​
    const styles = {
      message: {
        width: '70%',
        margin: 10,
        padding: 10,
        backgroundColor: 'white',
        borderColor: '#979797',
        borderStyle: 'solid',
        borderWidth: 1,
        borderRadius: 10
      },
      incomingMessage: {
        alignSelf: 'flex-end',
        backgroundColor: '#E1FFC7'
      }
    }
    ​
    export default Message;

    Tidak ada yang perlu dijelaskan dari code diatas karena hanya sebuah component biasa yang menerima props item yang akan menampilkan message kedalam component Text.

  5. Karena kita memanggil component Compose, maka buat file Compose.js didalam folder src/components, kemudian masukkan code berikut:

    import React from 'react';
    import { View, StyleSheet, Keyboard, Button, TextInput } from 'react-native';
    ​
    class Compose extends React.Component {
        constructor(props) {
            super(props);
            this.submit = this.submit.bind(this);
        }
    ​
        //Membuat state text 
        state = {
            text: ''
        }
    ​
        //submit method yang berfungsi ketika tombol ditekan
        submit() {
            //mengirim nilai ke database berdasarkan state text yang diterima
            this.props.submit(this.state.text);
            //mengatur state text menjadi kosong
            this.setState({
                text: ''
            })
            //menutup keyboard
            Keyboard.dismiss();
        }
    ​
        render(){
            return (
                <View style={styles.compose}>
                    <TextInput
                        style={styles.composeText}
                        //value diatur berdasarkan nilai dari state text
                        value={this.state.text}
                        //ketika text berubah maka akan melakukan set text
                        onChangeText={(text) => this.setState({text})}
                        //Ketika user memasukkan text dan meng-klik return pada phone keyboard maka akan disubmit.
                        onSubmitEditing={(event) => this.submit()}
                        editable = {true}
                        maxLength = {40}
                    />
                    <Button
                        //ketika tombol ditekan maka akan memanggil method submit
                        onPress={this.submit}
                        title="Send"
                    />
                </View>
            )
        }
    } 
    ​
    const styles = StyleSheet.create({
      composeText: {
        width: '80%',
        paddingHorizontal: 10,
        height: 40,
        backgroundColor: 'white',
        borderColor: '#979797',
        borderStyle: 'solid',
        borderWidth: 1,
      },
      compose: {
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
        margin: 10
      }
    });
    ​
    export default Compose;

    Karena Message.js dan Compose.js telah dibuat, buka file ChatScreen.js kemudian import kedua file tersebut:

    import Message from '../components/Message';
    import Compose from '../components/Compose';
  6. Pada step ke-4 bagian <Compose submit={postMessage} />, kita mengirimkan props submit menggunakan function postMessage. Maka buka file api.js kemudian tambahkan code berikut:

    export const postMessage = (message) => {
        if (Boolean(message)) {
            pushData('messages', {
                incoming: false,
                message
            })
        }
    }

    Penjelasan: Jika ada data yang diterima maka kita akan akan mengirim nilai pushData dengan name messages yang berisi data incoming = false dan message itu sendiri. Karena kita menggunakan function pushData, maka perbaharui import from Firebase menjadi:

    import { setListener, pushData, initialize } from './firebase';
  7. Buka file firebase.js kemudian tambahkan code berikut untuk membuat function pushData:

    export const pushData = (endpoint, data) => {
        return firebase.database().ref(endpoint).push(data);
    }

    Penjelasan: Code diatas berfungsi untuk melakukan push data ke dalam database Firebase dengan menerima value yang dikirimkan.

Baca Juga: Mengenal Component React Native

Sampai pada tahap ini, aplikasi chatting whatsapp clone telah berhasil dibuat dan dapat berjalan sebagaimana mestinya. Saat aplikasi di-load maka akan tampak seperti ini :

Kemudian klik Navigate ke ChatScreen, maka akan tampak seperti ini:

Kemudian saat mengisi text lalu tekan send maka data pada chatscreen akan diperbaharui

Sekian case sederhana tentang bagaimana cara berinteraksi dengan database secara real-time dimana pada case kali ini kita memanfaatkan service dari Firebase. Buat kamu yang masih kebingungan meyatukan potongan code diatas harap dibaca secara perlahan atau bisa dengan menyalin repository github. Semoga bermanfaat.

Category:
Share:

Comments