A Step-by-Step Guide to Efficient Data Retrieval and Image Handling with Firebase

Requirements

build.gradle.kts (Module :app)

    implementation("com.github.bumptech.glide:glide:4.16.0")

Codes

activity_manage_workshop.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".admin.ManageWorkshopActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:navigationIcon="@drawable/arrow_left"
            app:title="Manage Workshops" />
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/create"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="12dp"
        android:src="@drawable/plus_circle" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

ManageWorkshopActivity.java

package com.example.techsupporthub.admin;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.techsupporthub.R;
import com.example.techsupporthub.adapters.WorkshopAdapter;
import com.example.techsupporthub.model.Workshop;
import com.example.techsupporthub.utils.Constants;
import com.example.techsupporthub.utils.Utils;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.List;

public class ManageWorkshopActivity extends AppCompatActivity {

    private RecyclerView recyclerView;
    private WorkshopAdapter workshopAdapter;
    private List<Workshop> workshopList;
    private DatabaseReference databaseReference;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_manage_workshop);

        MaterialToolbar toolbar = findViewById(R.id.toolbar);
        toolbar.setNavigationOnClickListener(v -> finish());

        recyclerView = findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        workshopList = new ArrayList<>();
        workshopAdapter = new WorkshopAdapter(this, workshopList);
        recyclerView.setAdapter(workshopAdapter);

        findViewById(R.id.create).setOnClickListener(v -> startActivity(new Intent(ManageWorkshopActivity.this, CreateWorkshopActivity.class)));

        // Initialize Firebase Realtime Database reference
        databaseReference = Utils.getDatabaseReference(Constants.WORKSHOP_DB);

        // Retrieve workshops from Firebase Realtime Database
        retrieveWorkshops();
    }

    private void retrieveWorkshops() {
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                workshopList.clear();
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    Workshop workshop = snapshot.getValue(Workshop.class);
                    if (workshop != null) {
                        workshopList.add(workshop);
                    }
                }
                workshopAdapter.notifyDataSetChanged();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.e("ManageWorkshopActivity", "Failed to read value.", databaseError.toException());
                Toast.makeText(ManageWorkshopActivity.this, "Failed to retrieve workshops", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

WorkshopAdapter.java

package com.example.techsupporthub.adapters;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.example.techsupporthub.R;
import com.example.techsupporthub.model.Workshop;

import java.util.List;

public class WorkshopAdapter extends RecyclerView.Adapter<WorkshopAdapter.WorkshopViewHolder> {

    private final Context context;
    private final List<Workshop> workshopList;

    public WorkshopAdapter(Context context, List<Workshop> workshopList) {
        this.context = context;
        this.workshopList = workshopList;
    }

    @NonNull
    @Override
    public WorkshopViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_workshop, parent, false);
        return new WorkshopViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull WorkshopViewHolder holder, int position) {
        Workshop workshop = workshopList.get(position);
        holder.titleTextView.setText(workshop.getTitle());
        holder.descriptionTextView.setText(workshop.getDescription());
        holder.startDateTextView.setText("Start Date: " + workshop.getStartDate());
        holder.endDateTextView.setText("End Date: " + workshop.getEndDate());

        // Load image using Glide
        Glide.with(context).load(workshop.getImageUrl()).into(holder.imageView);
    }

    @Override
    public int getItemCount() {
        return workshopList.size();
    }

    public static class WorkshopViewHolder extends RecyclerView.ViewHolder {
        ImageView imageView;
        TextView titleTextView;
        TextView descriptionTextView;
        TextView startDateTextView;
        TextView endDateTextView;

        public WorkshopViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView = itemView.findViewById(R.id.image_view);
            titleTextView = itemView.findViewById(R.id.title_text_view);
            descriptionTextView = itemView.findViewById(R.id.description_text_view);
            startDateTextView = itemView.findViewById(R.id.start_date_text_view);
            endDateTextView = itemView.findViewById(R.id.end_date_text_view);
        }
    }
}

item_workshop.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="<http://schemas.android.com/apk/res/android>"
    xmlns:app="<http://schemas.android.com/apk/res-auto>"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    app:cardUseCompatPadding="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <ImageView
            android:id="@+id/image_view"
            android:layout_width="match_parent"
            android:layout_height="150dp" />

        <TextView
            android:id="@+id/title_text_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Workshop Title"
            android:textSize="18sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/description_text_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:text="Workshop Description"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/start_date_text_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:text="Start Date: YYYY-MM-DD"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/end_date_text_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:text="End Date: YYYY-MM-DD"
            android:textSize="14sp" />
    </LinearLayout>
</com.google.android.material.card.MaterialCardView>