Cara Autentikasi Menggunakan Nomor Telepon pada Firebase


Assalamualaikum Warahmatullahi Wabarakatuh.

Pada kesempatan kali ini, saya akan mengajarkan kepada kalian mengenai cara Autentikasi atau Login menggunakan Nomor Telepon di aplikasi android, saat ini Firebase mempuyai fitur baru pada Firebase Authentication yaitu kita bisa login/masuk menggunakan nomor telepon, contohnya seperti pada Facebook Messenger atau WhatsApp.

Cara Autentikasi Menggunakan Nomor Telepon pada Firebase

Kalian dapat menggunakan Firebase Authentication untuk login menggunakan no telepon, lalu pengguna akan menerima SMS berupa kode sekali pakai yang digunakan untuk verifikasi, no telepon yang user masukan akan tersimpan di dalam dashboard Firebase Authentication.

Firebase Authentication: Menggunakan Nomor Telepon

1) Buat Project baru pada Android Studio kalian, jika project kalian belum terhubung dengan Firebase, Tambahkan Firebase terlebih dahulu pada Project tersebut. Tutorialnya bisa dilihat disini.

2) Buka file build.gradle (pada direktori app), lalu masukan library berikut ini pada Dependencies:

compile 'com.google.firebase:firebase-auth:11.4.0'

3) Agar project tersebut bisa login menggunakan nomor telepon, pertama tama kalian harus mengaktifkan metode login menggunakan no telepon pada Firebase Authentication, seperti pada gambar berikut ini:

WildanTechnoArt-Mengaktifkan Metode Login Ponsel

4) Kembali pada project android studio, disini kita akan menggunakan 2 buah activity, activity pertama akan kita gunakan untuk login dan verifikasi, sedangkan yang kedua, digunakan sebagai menu utama, setelah kita berhasil login menggunakan no telepon.

Buat Class/Activity baru bernama login.java dan activity_login.xml, activity ini akan kita gunakan untuk login dan verifikasi nomor telepon, untuk designnya, buatlah sesederhana mungkin, seperti ini:

WildanTechnoArt-Design Layout Login Activity Menggunakan Nomor Telepon

Berikut ini merupakan kode xml pada layout tersebut:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="28dp"
    android:gravity="center"
    android:orientation="vertical"
    tools:context="cianjur.developer.net.firebaseexample.login">

    <TextView
        android:id="@+id/no_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="+62"
        android:textSize="18sp"
        android:textStyle="bold"
        android:layout_alignBottom="@+id/phone"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignTop="@+id/phone" />

    <EditText
        android:id="@+id/phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_toRightOf="@+id/no_id"
        android:hint="Nomor Telepon"
        android:inputType="phone" />

    <EditText
        android:id="@+id/setVertifi"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/phone"
        android:layout_toLeftOf="@+id/vertifi"
        android:hint="6 Digit Kode Vertifikasi"
        android:inputType="number"
        android:maxLength="6"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <Button
        android:id="@+id/verifi"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="verifi"
        android:layout_above="@+id/linearLayout"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_below="@+id/setVertifi"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <Button
            android:id="@+id/login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="login" />

        <Button
            android:id="@+id/resend"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="resend" />
    </LinearLayout>
</RelativeLayout>

5) Selanjutnya kita akan membuat satu activity lagi, yang akan kita gunakan sebagai menu utama aplikasi, akan terbuka setelah kita berhasil login dan verifikasi, buat activity tersebut dan berinama main_menu.

Baca Juga:

Untu designnya saya hanya menggunakan 1 TextView dan RelativeLayout sebagai containernya.

WildanTechnoArt-Design Main Menu Layout - Firebase Autentikasi

kode xml pada activity_main_menu:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="cianjur.developer.net.firebaseexample.main_menu">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Selamat Datang Di WILDAN TECHNO ART"
        android:textSize="18sp"
        android:textStyle="bold" />
</RelativeLayout>

6) Buka file login.java, lalu kalian masukan semua source code berikut ini, pada beberapa beris kode tersebut sudah saya deskripsikan secara singkat mengenai fungsi-funginya:

package cianjur.developer.net.firebaseexample;

import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.FirebaseException;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthInvalidCredentialsException;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;

import java.util.concurrent.TimeUnit;

public class login extends AppCompatActivity implements OnClickListener{

    //Variable Untuk Komponen-komponen Yang Diperlukan
    private EditText NoTelepon, SetKode;
    private Button Masuk, Verifikasi, Resend;
    private TextView PhoneID;

    //Variable yang Dibutuhkan Untuk Autentikasi
    private FirebaseAuth auth;
    private FirebaseAuth.AuthStateListener stateListener;
    private PhoneAuthProvider.ForceResendingToken resendToken;
    private PhoneAuthProvider.OnVerificationStateChangedCallbacks callbacks;
    private String VerifikasiID;
    private String No_Telepon;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        PhoneID = findViewById(R.id.no_id);
        NoTelepon = findViewById(R.id.phone);
        SetKode = findViewById(R.id.setVerifi);
        Masuk = findViewById(R.id.login);
        Masuk.setOnClickListener(this);
        Verifikasi = findViewById(R.id.verifi);
        Verifikasi.setOnClickListener(this);
        Resend = findViewById(R.id.resend);
        Resend.setOnClickListener(this);
        Resend.setEnabled(false);

        //Menghubungkan Project Dengan Firebase Authentication
        auth = FirebaseAuth.getInstance();
        stateListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                //Meneteksi Apakah Ada User Yang Sedang Login (Belum Logout)
                if(user != null){
                    //Jika Ada, User Tidak perlu Login Lagi, dan Langsung Menuju Acivity Yang Dituju
                    startActivity(new Intent(login.this, main_menu.class));
                    finish();
                }
            }
        };
    }

    @Override
    protected void onStart() {
        super.onStart();
        //Melampirkan Listener pada FirebaseAuth saat Activity Dimulai
        auth.addAuthStateListener(stateListener);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if(stateListener != null){
            //Menghapus Listener pada FirebaseAuth saat Activity Dihentikan
            auth.removeAuthStateListener(stateListener);
        }
    }

    private void setupVerificationCallback(){
        callbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
            @Override
            public void onCodeSent(String verificationId, PhoneAuthProvider.ForceResendingToken token) {
                // Callback didalam sini akan dipanggil/dieksekusi saat terjadi proses pengiriman kode
                // Dan User Diminta untuk memasukan kode verifikasi

                // Untuk Menyimpan ID verifikasi dan kirim ulang token
                VerifikasiID = verificationId;
                resendToken = token;
                Resend.setEnabled(true);
                Toast.makeText(getApplicationContext(), "Mendapatkan Kode Verifikasi", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onVerificationCompleted(PhoneAuthCredential Credential) {
                // Callback disini akan dipanggil saat Verifikasi Selseai atau Berhasil
                Toast.makeText(getApplicationContext(), "Verifikasi Selesai", Toast.LENGTH_SHORT).show();
                signInWithPhoneAuthCredential(Credential);
            }

            @Override
            public void onVerificationFailed(FirebaseException e) {
                // Callback disini akan dipanggil saat permintaan tidak valid atau terdapat kesalahan
                Toast.makeText(getApplicationContext(), "Verifikasi Gagal, Silakan Coba Lagi", Toast.LENGTH_SHORT).show();
            }
        };
    }

    private void signInWithPhoneAuthCredential(PhoneAuthCredential credential){
        auth.signInWithCredential(credential)
                .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if(task.isSuccessful()){
                            //Sign In Berhasil
                            startActivity(new Intent(login.this, main_menu.class));
                            finish();
                        }else{
                            //Sign In Gagal
                            if(task.getException() instanceof FirebaseAuthInvalidCredentialsException){
                                // Kode Yang Dimasukan tidal Valid.
                                Toast.makeText(getApplicationContext(), "Kode yang dimasukkan tidak valid", Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.login:
                No_Telepon = PhoneID.getText()+NoTelepon.getText().toString();
                setupVerificationCallback();
                PhoneAuthProvider.getInstance().verifyPhoneNumber(
                        No_Telepon, //NO Telepon Untuk Di Verifikasi
                        60, //Durasi Waktu Habis
                        TimeUnit.SECONDS, //Unit Timeout
                        this, //Activity
                        callbacks); // OnVerificationStateChangedCallbacks
                Toast.makeText(getApplicationContext(), "Memverifikasi, Mohon Tunggu", Toast.LENGTH_SHORT).show();
                NoTelepon.setText("");
                break;

            case R.id.verifi:
                String verifiCode = SetKode.getText().toString();
                if(TextUtils.isEmpty(verifiCode)){
                    //Memberi Pesan pada user bahwa kode verifikasi tidak boleh kosong saat menekan Tombol Verifikasi
                    Toast.makeText(getApplicationContext(),"Masukan Kode Verifikasi", Toast.LENGTH_SHORT).show();
                }else{
                    //Memverifikasi Nomor Telepon, Saat Tombol Verifikasi Ditekan
                    PhoneAuthCredential credential = PhoneAuthProvider.getCredential(VerifikasiID, verifiCode);
                    signInWithPhoneAuthCredential(credential);
                    Toast.makeText(getApplicationContext(),"Sedang Memverifikasi", Toast.LENGTH_SHORT).show();
                }
                break;

            case R.id.resend:
                No_Telepon = PhoneID.getText()+NoTelepon.getText().toString();
                setupVerificationCallback();
                PhoneAuthProvider.getInstance().verifyPhoneNumber(
                        No_Telepon, //NO Telepon Untuk Di Vertifikai
                        60, //Durasi Waktu Habis
                        TimeUnit.SECONDS, //Unit Timeout
                        this, //Activity
                        callbacks, // OnVerificationStateChangedCallbacks
                        resendToken); // Digunakan untuk mengirim ulang kembali kode verifikasi
                Toast.makeText(getApplicationContext(), "Mengirim Ulang Kode Verifikasi", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

Penjelasan:

Ada beberapa baris kode yang mungkin belum kalian pahami, disini saya akan menembahkan mengenai penjelasan pada baris-baris kode tersebut:
  • Untuk memverifikasi nomor telepon, kita menggunakan metode PhoneAuthProvider.vertifyPhoneNumber(), yang mempunyai parameter berupa, Nomor_Telepon, Durasi, Unit Timeout, Activity, Callback.
  • Terkadang secara otomatis user akan langsung login setelah kode verifikasi diterima, tampa perlu memasukannya secara manual.
  • Saat memanggil PhoneAuthProvider.verifyPhoneNumber, Kita juga harus memberikan instance pada  OnVerificationStateChangedCallbacks, yang berisi implementasi fungsi callback yang menangani hasil permintaan.
  • Pada tombol Varifikasi yang sudah saya buat, disana terdapat Objek PhoneAuthCredential, yang digunakan untuk memverifikasi secara manual setelah kita mendapatkan kode verifikasinya.
  • Pada Tombol Resend, untuk pengkodeannya hampir sama dengan Tombol Verifikasi, yang membedakan adalah pada metode PhoneAuthProvider.vertifyPhoneNumber(), kita menambahkan parameter berupa callback, yang digunakan untuk mengirim ulang kode verifikasi pada user.
  • Agar pengguna bisa login, kita membuat sebuah metode bernama signInWithPhoneAuthCredential(), setelah mendapatkan Objek Credential, baik itu didalam onVerificationCompleted() atau didapat dari PhoneAuthProvider.getCredential(), didalam metode terdapat kodisi dimana jika task.isSuccessful(), atau dengan artian berhasil untuk login/diverifikasi dan tidak ada masalah, maka apa yang terjadi, dalam program yang saya buat, jika sukses, activity akan berpindah pada activity kedua yaitu activity_main_menu, yang suah kita buat sebelumnya.

Jangan lupa, untuk mengetahui user sudah login atau tidak, disana kita menggnakan FirebaseAuth,getInstance() dan FirebaseAuth.AuthStateListener(), lalu di lampirkan pada metode onStart() dan dihapus pada metode onStop().

auth = FirebaseAuth.getInstance();
        stateListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                //Meneteksi Apakah Ada User Yang Sedang Login (Belum Logout)
                if(user != null){
                    //Jika Ada, User Tidak perlu Login Lagi, dan Langsung Menuju Acivity Yang Dituju
                    startActivity(new Intent(login.this, main_menu.class));
                    finish();
                }
            }
        };

@Override
    protected void onStart() {
        super.onStart();
        //Melampirkan Listener pada FirebaseAuth saat Activity Dimulai
        auth.addAuthStateListener(stateListener);
    }

    @Override
    protected void onStop() {
        super.onStop();
        if(stateListener != null){
            //Menghapus Listener pada FirebaseAuth saat Activity Dihentikan
            auth.removeAuthStateListener(stateListener);
        }
    }

Agar user bisa logout, kalian dapat menggunakan metode signOut(), seperti berikit ini:

auth.getInstance().signOut();

Untuk mencegah spam, Firebase memberikan batasan jumlah pesan SMS yang dapat dikirimkan ke 1 nomor telepon dalam jangka waktu tertentu. Jika batas ini terlewati, permintaan verifikasi nomor telepon dapat tertahan.

Selanjutnya coba kalian jalankan project tersebut langsung pada perangkat android dan jangan menggunakan emulator untuk mengujinya karena Firebase tidak akan merespon jika kita menggunakan emulator.

Demikian tutorial dari saya, mengenai Penggunaan Firebase Authentication dengan menggnakan nomor telepon, jika artikel ini bermanfaat, silakan share pada teman teman kalian, mohon maaf bila ada kesalahan. Wassalamualaikum Warahmatullahi Wabarakatuh.

Wildan M Athoillah
Wildan M Athoillah Blogger dan spesialis pembuat aplikasi android.