Cara Menampilkan Gambar dari Firebase Storage pada RecyclerView
Assalamualaikum Warahmatullahi Wabarakatuh.
Untuk menampilkan gambar yang tersimpan pada Storage, kita memerlukan URL download dari file yang telah di upload, untuk itu setelah user menupload gambar pada Storage, kita perlu menyimpan URL dari file tersebut, disini kita akan menyimpan URLnya pada meyimpanan Realtime Database, setelah itu program akan menampilkan semua gambar yang tersimpan pada RecyclerView melalui URL dari gambar yang tersimpan.
Untuk pembuatan program berikut ini, kita memerlukan 2 library tambahan dari Firebase, yaitu : Realtime Database dan FirebaseUI Realtime Database
- Firebase Realtime Database : Library yang akan digunakan untuk menyimpan URL download dari file yang telah di upload pada Storage.
- FirebaseUI Realtime Database : Sebuah library yang memudahkan kita untuk menghubungkan data dari Database pada RecyclerView menggunakan FirebaseRecyclerAdapter.
Materi lainnya yang direkomendasikan:
- Cara Membuat Aplikasi CRUD Menggunakan Firebase Realtime Database
- Belajar Menggunakan FirebaseUI untuk Autentikasi
- Mengirim Notifikasi Menggunakan Firebase Cloud Messaging
Materi ini adalah kelanjutan dari tutorial Belajar Cara Mengupload File pada Firebase Storage jadi saya sarankan kalian telah mengikuti tutorial yang saya berikan sebelumnya, tapi jika sudah paham, kalian boleh melewati tutorial tersebut.
Cara Menampilkan Gambar dari Firebase Storage pada RecyclerView
1) Pertama kalian tambahkan beberapa library berikut ini kedalam dependencies pada file build.gradle (app module).
implementation 'com.android.support:design:27.1.1'
implementation 'com.google.firebase:firebase-database:16.0.1'
implementation 'com.firebaseui:firebase-ui-database:3.2.2'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.github.bumptech.glide:glide:4.7.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
2) Disini kita menggunakan Firebase Realtime Database, secara default aturan keamanan dari Realtime Database tersebut diharuskan user untuk terautentikasi agar dapat membaca atau menulis data, seperti berikut ini.Karena aplikasi yang akan kita buat tidak akan menggunakan fitur autentikasi didalamnya, untuk itu kita perlu merubahnya ke aturan public seperti ini.
{
"rules": {
".read": true,
".write": true
}
}
3) Berikutnya buat layout item untuk RecyclerView, karena hanya gambar saja yang akan ditampilkan, jadi kita hanya perlu menambahkan ImageView kedalamnya. Klik kanan pada direktori layout, buat layout baru, berinama misalnya "recycler_layout".<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp">
<ImageView
android:id="@+id/gambar"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
tools:ignore="ContentDescription" />
</RelativeLayout>
4) Buat kelas modelnya, class ini digunakan untuk menentukan jenis data dan data apa saja yang akan dimasukan, buat class baru, berinama "DataModels".package cianjur.developer.net.firebaseexample;
public class DataModels {
private String image_url;
//Konstruktor kosong, untuk data snapshot pada Firebase Realtime Database
public DataModels() {}
public DataModels(String image_url) {
this.image_url = image_url;
}
public String getImage_url() {
return image_url;
}
}
Pada class tersebut kita membuat sebuah variable untuk menetukan nama dan jenis data yang akan dimasukan pada Database, lalu konstuktor kosong untuk data snapshot pada Database dan terakhir yaitu metod getter untuk mendapatkan value dari variable image_url.5) Buat Activity baru, berimana misalnya "ImageStorage", activity ini akan gunakan untuk menampilkan semua gambar yang tersimpan pada Storage, disini kita cukup menambahkan RecyclerView dan ProgressBar.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="cianjur.developer.net.firebaseexample.ImageStorage">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_margin="8dp" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
</RelativeLayout>
6) Buka kembali pada activity_main.xml yang sudah kalian buat pada tutorial sebelumnya, disini kita cukup manambahkan sebuah Button untuk berpindah activity.7) Pada MainActivity.java, kita akan mengambil download URL dari child yang telah ditentukan pada uploadTask, didalam method addOnSuccessListener(), kita tambahkan referensi Database untuk menentukan lokasi penyimpanan URL file lalu menyimpannya.
DatabaseReference databaseReference;
private Button ShowImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Upload = findViewById(R.id.upload);
Upload.setOnClickListener(this);
UnggahGambar = findViewById(R.id.select_Image);
UnggahGambar.setOnClickListener(this);
ImageContainer = findViewById(R.id.imageContainer);
progressBar = findViewById(R.id.progressBar);
ShowImage = findViewById(R.id.image_storage);
//Mendapatkan Referensi dari Firebase Storage
reference = FirebaseStorage.getInstance().getReference();
//Mendapatkan Referensi dari Firebase Realtime Database
databaseReference = FirebaseDatabase.getInstance().getReference();
ShowImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, ImageStorage.class));
}
});
}
//Method ini digunakan untuk mengupload gambar pada Storage
private void uploadImage(){
//Mendapatkan data dari ImageView sebagai Bytes
ImageContainer.setDrawingCacheEnabled(true);
ImageContainer.buildDrawingCache();
Bitmap bitmap = ((BitmapDrawable) ImageContainer.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
//Mengkompress bitmap menjadi JPG dengan kualitas gambar 100%
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bytes = stream.toByteArray();
String namaFile = UUID.randomUUID()+".jpg"; //Nama Gambar (Secara Random)
final String pathImage = "gambar/"+namaFile; //Lokasi lengkap dimana gambar akan disimpan
UploadTask uploadTask = reference.child(pathImage).putBytes(bytes);
uploadTask.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
if(task.isSuccessful()){
//Mendapatkan URL download dari gambar yang telah disimpan pada Storage
reference.child(pathImage).getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
//Menyimpan URL pada Variable String
String downloadURL = uri.toString();
//Menentukan referensi lokasi data url yang akan disimpan
databaseReference.child("gambar").push().setValue(new DataModels(downloadURL));
progressBar.setVisibility(View.GONE);
Toast.makeText(MainActivity.this, "Uploading Berhasil", Toast.LENGTH_SHORT).show();
ImageContainer.setVisibility(View.GONE);
}
});
}else{
progressBar.setVisibility(View.GONE);
Toast.makeText(MainActivity.this, "Uploading Gagal", Toast.LENGTH_SHORT).show();
}
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
//Method ini digunakan untuk menghitung persentase proses uploading file
progressBar.setVisibility(View.VISIBLE);
double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
progressBar.setProgress((int) progress);
}
});
}
8) Setelah itu kita buat class ViewHoler, class ini digunakan untuk menentukan View-view yang akan digunakan pada RecyclerView, sebelumnya view tersebut sudah kita buat pada layout bernama "recycler_layout.xml".package cianjur.developer.net.firebaseexample;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
public class RecyclerAdapter extends RecyclerView.ViewHolder{
public RecyclerAdapter(View itemView) {
super(itemView);
}
void setDisplayImage(String imageUrl, Context context) {
ImageView image = itemView.findViewById(R.id.gambar);
Glide.with(context)
.load(imageUrl)
.into(image);
}
}
Pada class tersebut, kita membuat sebuah method dengan parameter berupa variable yang akan mengisi data/value pada ImageView tersebut, menggunakan library Glide.9) Selanjutnya buka class ImageStorage,java untuk persiapan, masukan source code seperti berikut ini.
//========= WILDAN TECHNO ART =========//
/*
* Belajar menggunakan Firebase Storage
* Bersama Wildan M Athoillah
*/
//======= CIANJUR APPS DEVELOPER ======//
package cianjur.developer.net.firebaseexample;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class ImageStorage extends AppCompatActivity {
//Deklarasi Variable
private DatabaseReference reference;
private RecyclerView recyclerView;
private FirebaseRecyclerAdapter<DataModels, RecyclerAdapter> recyclerAdapter;
private FirebaseRecyclerOptions<DataModels> options;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_storage);
getSupportActionBar().setTitle("Image Storage");
recyclerView = findViewById(R.id.recyclerView);
progressBar = findViewById(R.id.progressBar);
//Digunakan untuk mengatur dan memposisikan item didalam RecyclerView
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//Digunakan agar ukuran RecyclerView tidak berubah saat menambahkan item atau menghapusnya
recyclerView.setHasFixedSize(true);
//Mendapatkan referensi dari Database
reference = FirebaseDatabase.getInstance().getReference();
firebaseReyclerViewAdapter();
}
Pada FirebaseRecyclerAdapter diperlukan 2 buah parameter yaitu data model yang akan digunakan dan view holder.10) Selanjutnya pada method firebaseRecyclerViewAdapter(), masukan source code berikut ini beserta penjelasannya.
//========= WILDAN TECHNO ART =========//
/*
* Belajar menggunakan Firebase Storage
* Bersama Wildan M Athoillah
*/
//======= CIANJUR APPS DEVELOPER ======//
package cianjur.developer.net.firebaseexample;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class ImageStorage extends AppCompatActivity {
//Deklarasi Variable
private DatabaseReference reference;
private RecyclerView recyclerView;
private FirebaseRecyclerAdapter<DataModels, RecyclerAdapter> recyclerAdapter;
private FirebaseRecyclerOptions<DataModels> options;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_storage);
getSupportActionBar().setTitle("Image Storage");
recyclerView = findViewById(R.id.recyclerView);
progressBar = findViewById(R.id.progressBar);
//Digunakan untuk mengatur dan memposisikan item didalam RecyclerView
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//Digunakan agar ukuran RecyclerView tidak berubah saat menambahkan item atau menghapusnya
recyclerView.setHasFixedSize(true);
//Mendapatkan referensi dari Database
reference = FirebaseDatabase.getInstance().getReference();
firebaseReyclerViewAdapter();
}
//Method ini digunakan untuk mengubungkan data dari Database pada RecyclerView
private void firebaseReyclerViewAdapter(){
// Mengatur setelah opsi untuk FirebaseRecyclerAdapter
options = new FirebaseRecyclerOptions.Builder<DataModels>()
// Referensi Database yang akan digunakan beserta data Modelnya
.setQuery(reference.child("gambar"), DataModels.class)
.setLifecycleOwner(this) //Untuk menangani perubahan siklus hidup pada Activity/Fragment
.build();
// Digunakan untuk menghubungkan View dengan data Models
recyclerAdapter = new FirebaseRecyclerAdapter<DataModels, RecyclerAdapter>(options) {
@Override
protected void onBindViewHolder(@NonNull RecyclerAdapter holder, int position, @NonNull DataModels model) {
//Mendapatkan data dari Database yang akan ditampilkan pada RecyclerView
holder.setDisplayImage(model.getImage_url(), ImageStorage.this);
progressBar.setVisibility(View.GONE);
}
@NonNull
@Override
public RecyclerAdapter onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//Mengubungkan adapter dengan Layout yang akan digunakan
return new RecyclerAdapter(LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_layout, parent, false));
}
};
recyclerView.setAdapter(recyclerAdapter);
}
}
Demo aplikasi :Gambar yang diupload akan tersimpan pada Storage.
Dan URL download dari file tersebut akan tersimpan pada Database.
Terimakasih atas kunjungannya, semoga tutorial yang saya berikan bisa bermanfaat untuk kalian semua, selebihnya, mohon maaf bila ada kesalahan.
Wassalamualaikum Warahmatullahi Wabarakatuh.