Apa jadinya apabila informasi yang bersifat
pribadi dapat diakses secara publik yang bukan merupakan pemilik
informasi tersebut? Maka dalam kondisi seperti ini, fitur
authentication akan sangat dibutuhkan untuk menangani masalah
permission untuk
user yang akan menggunakan aplikasi kita. Melanjutkan
case sebelumnya, Membuat Aplikasi Chatting.
Tahap Persiapan
Sebelum kita membuat fitur
authentication menggunakan React Native, maka langkah pertama yang harus dilakukan adalah mengaktifkan
service authentication di Firebase. Masih menggunakan
project Firebase sebelumnya, lakukan beberapa hal berikut:
-
Pada menu di sisi kiri, pilih Authentication

-
Kemudian pilih tab SIGN-IN METHOD

-
Kemudian Enable pada bagian Email/Password

Setelah kebutuhan terakait
service Firebase telah diaktifkan, maka tiba saatnya untuk berinteraksi dengan React Native.
Authentication, selalu berkaitan dengan
Login &
Sing Up,
dua hal yang saling terkait satu sama lainnya. Maka pada kesempatan
kali ini kita akan membuat keduanya agar dapat digunakan sebagaimana
mestinya.
Login & Sign Up Screen
Sebelum beranjak pada topik sub heading
diatas, kita akan mengatur route terlebih dahulu yang akan bertindak
sebagai navigasi dalam aplikasi yang akan kita bangun. Oleh karena itu,
buka file
src/config/routes.js kemudian modifikasi menjadi seperti berikut:
import React from 'react';
import Login from '../screens/Login';
import Signup from '../screens/Signup';
import Home from '../screens/Home';
import ChatScreen from '../screens/ChatScreen';
const routes = {
login: { screen: Login },
signup: { screen: Signup },
home: { screen: Home },
chat: { screen: ChatScreen }
}
export default routes;
Cara kerja dari
code diatas masih sama, yakni mengatur navigasi untuk berpindah antar
screen. Perlu diperhatikan, kita meng-
import dua
screen tambahan (baca:
Login dan
Singup), maka buat file tersebut satu persatu. Pertama, buat file
Login.js di dalam folder
screens kemudian ketikkan
code berikut:
import React from 'react';
import { login } from '../services/api';
import { View, StyleSheet, Image, ScrollView, TextInput, Button, Text, TouchableOpacity } from 'react-native';
import SplashScreen from '../components/SplashScreen';
import { NavigationActions } from 'react-navigation';
export default class Login extends React.Component {
render() {
return(
<View style={styles.container}>
<Image
style={[ styles.logo ]}
source={require('../assets/img/whatsapplogo.png')} />
<ScrollView style={styles.container}>
<TextInput
ref={(textInput) => this._user = textInput }
style={styles.inputField}
value={this.state.text}
onChangeText={(user) => this.setState({user})}
onSubmitEditing={(event) => this._password.focus()}
onFocus={ () => this.clearValidationErrors() }
editable={true}
maxLength={40}
multiline={false}
placeholder="Masukkan Email"
/>
<TextInput
ref={(textInput) => this._password = textInput }
style={styles.inputField}
value={this.state.text}
onChangeText={(password) => this.setState({password})}
onSubmitEditing={(event) => this.submit()}
editable={true}
secureTextEntry={true}
maxLength={40}
multiline={false}
placeholder="Masukkan Password"
/>
{ this.state.error &&
<View style={styles.validationErrors}>
<Text style={styles.error}>{this.state.error}
</Text>
</View>
}
<View style={styles.buttonStyle}>
{ this.state.loading ?
<SplashScreen /> :
<Button
onPress={() => this.submit()}
title="Masuk" />
}
</View>
<View style={styles.redirectLink}>
<Text>Tidak punya akun? </Text>
<TouchableOpacity onPress={() =>
this.props.navigation.navigate('signup')}>
<Text style={styles.link}>Daftar</Text>
</TouchableOpacity>
</View>
<View style={styles.copyright}>
<Text style={{fontSize: 18, color: '#19B5FE'}}>https://daengweb.id</Text>
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white'
},
logo: {
width: '100%',
height: 200
},
inputField: {
marginTop: 20,
alignSelf: 'center',
height: 55,
width: '80%',
backgroundColor: '#FAFAFA',
borderWidth: 1,
paddingHorizontal: 10,
borderRadius: 10,
borderColor: "#CACACA"
},
redirectLink: {
marginTop: 20,
flex: 1,
flexDirection: 'row',
alignSelf: 'center'
},
link: {
color: 'blue'
},
validationErrors: {
flexDirection: 'row',
justifyContent: 'center',
},
error: {
marginTop: 10,
textAlign: 'center',
color: 'red'
},
buttonStyle: {
marginTop: 15,
flex: 1
},
copyright: {
marginTop: 15,
flex: 1,
alignSelf: 'center'
}
})
Penjelasan: Pada layer pertama akan me-
load gambar menggunakan
Image component dari
directory src/assets/img/whatsapplogo.png yang dapat kamu
download di
Github. Pada layer kedua, kita memiliki dua buah
TextInput component yang diapit oleh
ScrollView component agar pada
device yang tidak dapat me-
load component secara penuh dapat di-
scroll. Adapun properti yang mengikuti
TextInput masih sama seperti sebelumnya, yang membedakan hanya pada bagian
TextInput untuk
password terdapat
prop secureTextEntry yang berfungsi untuk mengatur apakah
text pada
input field akan ditampilkan atau tidak.
Pada layer selanjutnya yang terletak dibawah
input field, terdapat bagian yang akan menampilkan
errors yang diperoleh dari Firebase:
{ this.state.error &&
<View style={styles.validationErrors}>
<Text style={styles.error}>{this.state.error}
</Text>
</View>
}
Kita juga memiliki sebuah
Buttonyang menggunkan
event onpress, dimana ketika tombol tersebut ditekan maka akan memicu
submit function. Sedangkan untuk function
submit
akan kita tambahkan nanti sebab memiliki penjelasan tersendiri agar
tidak kebingungan. Kemudian di layer terakhir, kita memiliki memiliki
tombol untuk berpindah ke
Sign Up screen.
Masih di dalam file
Login.js, tambahkan
code berikut yang merupakan
function submit:
async submit(){
try {
const response = await login(this.state.user, this.state.password);
if (response) {
this.setState({loading: true})
setTimeout(() => {
this.clearAndNavigate('home')
}, 1000);
}
} catch ({ message }) {
this.setState({
error: message
})
}
}
Penjelasan: Kita menggunakan
method login yang didapatkan dari
service/api.js dengan mengirimkan parameter
state user dan
password. Apabila
response bernilai
true, maka
state loading akan diset ke
true, kemudian dalam waktu satu menit kedepan akan mengirimkan parameter
home ke
clearAndNavigate function. Apabila
authentication gagal, maka
state error akan di
set dengan
value message (baca:
message ini berisi pesan error yang didapatkan dari Firebase).
Buat
function berikutnya yang bernama
clearAndNavigate:
clearAndNavigate(screen) {
this.setState({
user: '',
password: ''
})
Keyboard.dismiss();
this.isAuthenticated = true;
this.props.navigation.dispatch(
NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'home' })
]
})
);
}
Penjelasan:
Function ini berfungsi untuk membersihkan
state username dan
password menggunakan
setState. Kemudian, kita menutup
keyboard dan menentukan nilai dari state
isAuthenticated menjadi
true, kemudian kita me-
replace navigation screen dengan
home screen. Kondisi yang diharapkan adalah dimana
user tidak diizinkan untuk kembali ke
Login atau
SignUp screen, jadi kita menggunakan teknik
dispatch navigation actions untuk mengimplementasikannya.
Ada yang ketinggalan, pada
TextInput username, kita mengatur
prop onFocus dengan memanggil
method clearValidationErrors, maka tambahkan
function berikut yang berfungsi untuk menghapus
error:
clearValidationErrors(){
this.setState({
error: false
})
}
Karena kita membutuhkan beberapa
state, diantaranya:
username, password, error, isAuthenticated, loading. Maka kita tetapkan nilai
defaultnya terlebih dahulu, tambahkan
code berikut:
state = {
user: '',
password: '',
error: false,
isAuthenticated: false,
loading: false
}
Pada
screen ini, kita tidak membutuhkan sebuah
header, maka
navigationOptions akan diset
null:
static navigationOptions = {
header: null
}
Authentication Logic
Izinkan saya untuk beranjak ke tahap
authentication logic terlebih dahulu, sedangkan untuk
SignUp screen kita
skip dulu dan akan dilanjutkan kemudian. Jika kita perhatikan, pada
Login.js terdapat
code untuk meng-
import SplashScreen, maka buat file
SplashScreen.js di dalam folder
src/components kemudian masukkan
code berikut:
import React from 'react';
import { View, ActivityIndicator } from 'react-native';
export default function SplashScreen(){
return (
<View style={{ flex: 1, justifyContent: 'center'}}>
<ActivityIndicator
animating={true}
style={[styles.centering, {height: 80}]}
size="large"
/>
</View>
)
}
const styles = {
centering: {
alignItems: 'center',
justifyContent: 'center',
padding: 8
}
}
Tak ada yang perlu dijelaskan dari code di atas, karena hanya sebuah
component biasa yang di dalamnya terdapat
ActivityIndicator yang akan memicu efek
loading. Langkah berikutnya adalah dengan membuat
service API, buka file
api.js yang terdapat di dalam folder
src/services, kemudian modifikasi menjadi seperti ini:
import { setListener, pushData, initialize, signup, login } from './firebase';
export const initApi = () => initialize();
export const getMessages = (updaterFn) => setListener('messages', updaterFn);
export const postMessage = (message) => {
if (Boolean(message)) {
pushData('messages', {
incoming: false,
message
})
}
}
export {
login,
signup
}
Pada file
firebase.js, tambahkan
function login dan
signup berikut:
export const login = (email, pass) =>
firebase.auth()
.signInWithEmailAndPassword(email, pass)
export const signup = (email, pass) =>
firebase.auth().createUserWithEmailAndPassword(email, pass);
Penjelasan: Masing-masing dari
function diatas menerima
value email dan
password, dimana akan dikirimkan ke Firebase untuk melakukan otentikasi baik berupa
login maupun
signup.
Sampai pada tahap ini fitur login telah selesai dan siap digunakan, adapun tampilannya tampak seperti dibawah ini

Karena kita belum memiliki
user, maka buat file
Signup.js di dalam folder
src/screens, kemudian masukkan
code berikut:
import React from 'react';
import { signup } from '../services/api';
import { View, StyleSheet, Image, ScrollView, TextInput, Button, Text, Keyboard, TouchableOpacity } from 'react-native';
import { NavigationActions } from 'react-navigation';
export default class Login extends React.Component {
static navigationOptions = {
header: null
}
state = {
user: '',
password: '',
isAuthenticated: false
}
async submit() {
try {
const response = await signup(this.state.user, this.state.password)
this._user.clear();
this._password.clear();
Keyboard.dismiss();
this.isAuthenticated = true;
this.props.navigation.dispatch(
NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'home' })
]
})
);
} catch ({ message }) {
this.setState({
error: message
})
}
}
render() {
return (
<View
style={styles.container}>
<Image
style={[ styles.logo ]}
source={require('../assets/img/whatsapplogo.png')} />
<ScrollView style={styles.container}>
<TextInput
ref={(textInput) =>this._user = textInput }
style={styles.inputField}
value={this.state.text}
onChangeText={(user) => this.setState({user})}
onSubmitEditing={(event) => this._password.focus()}
editable={true}
maxLength={40}
multiline={false}
placeholder="Masukkan Email"
/>
<TextInput
ref={(textInput) =>this._password = textInput }
style={styles.inputField}
value={this.state.text}
onChangeText={(password) => this.setState({password})}
onSubmitEditing={(event) => this.submit()}
editable={true}
secureTextEntry={true}
maxLength={40}
multiline={false}
placeholder="Masukkan Password"
/>
{ this.state.error &&
<View style={styles.validationErrors}>
<Text style={styles.error}>{this.state.error}</Text>
</View>
}
<View style={styles.buttonStyle}>
<Button
onPress={() => this.submit()}
title="Daftar" />
</View>
<View style={styles.redirectLink}>
<Text>Sudah punya akun? </Text>
<TouchableOpacity onPress={() =>
this.props.navigation.navigate('login')}>
<Text style={styles.link}>Masuk</Text>
</TouchableOpacity>
</View>
<View style={styles.copyright}>
<Text style={{fontSize: 18, color: '#19B5FE'}}>https://daengweb.id</Text>
</View>
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white'
},
logo: {
width: '100%',
height: 200
},
inputField: {
marginTop: 20,
alignSelf: 'center',
height: 55,
width: '80%',
backgroundColor: '#FAFAFA',
borderWidth: 1,
paddingHorizontal: 10,
borderRadius: 10,
borderColor: "#CACACA"
},
redirectLink: {
flex: 1,
flexDirection: 'row',
alignSelf: 'center'
},
link: {
color: 'blue'
},
validationErrors: {
flexDirection: 'row',
justifyContent: 'center',
},
error: {
marginTop: 10,
textAlign: 'center',
color: 'red'
},
buttonStyle: {
marginTop: 15,
flex: 1
},
copyright: {
marginTop: 15,
flex: 1,
alignSelf: 'center'
}
})
Tak ada yang perlu dijelaskan dari
code diatas, karena hampir mirip dengan
Login.js. Adapun tampilannya tampak seperti ini:
sumber:
https://daengweb.id/fitur-authentication-react-native