Open In App

How to Upload Excel/Google Sheet Data to Firebase Realtime Database in Android?

Last Updated : 14 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Firebase Realtime Database is the backend service which is provided by Google for handling backend tasks for your Android apps, IOS apps as well as your websites. It provides so many services such as storage, database, and many more. The feature for which Firebase is famous for its Firebase Realtime Database. By using Firebase Realtime Database in your app you can give live data updates to your users without actually refreshing your app. In this article, we will be uploading Google/Excel Sheet Data into the firebase real-time database. This can be useful when you are creating a quiz app where you have to upload a lot of question. In that case, you can upload your data using an excel sheet.

What we are going to build in this article?  

We will be building a simple application in which we will be uploading data into the firebase real-time database using Google/Excel Sheet. Firstly we will be selecting an excel file and then it will be uploaded to firebase by taking the total number of rows and columns and then a random id will be generated in which row-wise data will be stored.

Note that we are going to implement this project using Java/Kotlin language.


Step by Step Implementation

Step 1: Create a New Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio.

Step 2: Working with the AndroidManifest.xml file

For adding data to Firebase we should have to give permissions for accessing the internet. For adding these permissions navigate to the app > manifests > AndroidManifest.xml and Inside that file add the below permissions to it.  

<uses-permission android:name="android.permission.INTERNET" />

Step 3: Working with the build.gradle(app) file

Add these implementations into it

dependencies {
...
implementation("com.github.bumptech.glide:glide:4.16.0")
}

To add Firebase Database to your project refer to this article: How to Save Data to the Firebase Realtime Database in Android?

Step 4: Creating a URL for fetching our data from Google Spreadsheet

Create a simple Google Spreadsheet which is shown below. Make sure to use the same headers as shown in the below file. 

Layout_2

 

After you have created our excel file. Now we have to publish this excel file to use it inside our app. For publishing it.  

Publish_on_Web


After this a dialog box will pop up select type of web share as CSV and then click on publish.

Publish_on_Web2


 Now we have created a URL in which we will be getting the data in the CSV format. Also, a sharable link will appear copy it.

Note: this is the link which is used in the application created below.

Step 5: Working with the activity_main.xml file

Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file. Now, Create a layout file for each item in recyclerview. Navigate to the app > res > layout > Right-click on it > New > layout resource file and give the file name as items and add below code to it.

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:color="@color/white"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Upload Sheet Data to Firebase"
        android:textSize="20sp"
        android:textColor="@color/black"
        android:textStyle="bold"
        android:layout_gravity="center_horizontal"
        />

    <Button
        android:id="@+id/fetchButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:text="Fetch Data" />

    <Button
        android:id="@+id/uploadButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:text="Upload Data" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/sheetRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_marginTop="16dp" />

</LinearLayout>
items.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    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:elevation="8dp"
    app:cardCornerRadius="8dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="2dp">

        <ImageView
            android:id="@+id/idIVUser"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_margin="10dp" />

        <TextView
            android:id="@+id/idTVFirstName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_toEndOf="@id/idIVUser"
            android:layout_toRightOf="@id/idIVUser"
            android:text="First Name"
            android:textColor="@color/black"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/idTVLastName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/idTVFirstName"
            android:layout_marginTop="10dp"
            android:layout_toEndOf="@id/idIVUser"
            android:layout_toRightOf="@id/idIVUser"
            android:text="Last Name"
            android:textColor="@color/black"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/idTVEmail"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/idTVLastName"
            android:layout_marginTop="10dp"
            android:layout_toEndOf="@id/idIVUser"
            android:layout_toRightOf="@id/idIVUser"
            android:text="Email"
            android:textColor="@color/black"
            android:textSize="15sp" />

    </RelativeLayout>

</androidx.cardview.widget.CardView>


Design UI:

upload-sheet-data-home


Step 6: Creating a Modal class for storing our data   

For storing our data we have to create a new java class. For creating a new java class, Navigate to the app > java/kotlin > your app's package name > Right-click on it > New > Java/Kotlin class and name it as UserModal and add the below code to it. 

UserModal.java
package org.geeksforgeeks.demo;

public class UserModal {
  
    // variables for our first name, 
    // last name, email and avatar
    private String first_name;
    private String last_name;
    private String email;
    private String avatar;

    public String getFirst_name() {
        return first_name;
    }

    public void setFirst_name(String first_name) {
        this.first_name = first_name;
    }

    public String getLast_name() {
        return last_name;
    }

    public void setLast_name(String last_name) {
        this.last_name = last_name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public UserModal(String first_name, String last_name, String email, String avatar) {
        this.first_name = first_name;
        this.last_name = last_name;
        this.email = email;
        this.avatar = avatar;
    }
}
UserModal.kt
package org.geeksforgeeks.demo

class UserModal(
    var first_name: String,
    var last_name: String,
    var email: String,
    var avatar: String
)


Step 7: Creating an Adapter class for setting data to our RecyclerView item  

For creating a new Adapter class. Navigate to the app > Java/Kotlin > your app's package name > Right-click on it > New > Java/Kotlin class and name it as UserRVAdapter and add the below code to it. 

UserRVAdapter.java
package org.geeksforgeeks.demo;

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.squareup.picasso.Picasso;

import java.util.ArrayList;

public class UserRVAdapter extends RecyclerView.Adapter<UserRVAdapter.ViewHolder> {
  
    // variable for our array list and context.
    private ArrayList<UserModal> userModalArrayList;
    private Context context;

    // creating a constructor.
    public UserRVAdapter(ArrayList<UserModal> userModalArrayList, Context context) {
        this.userModalArrayList = userModalArrayList;
        this.context = context;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // inflating our layout file on below line.
        View view = LayoutInflater.from(context).inflate(R.layout.user_rv_item, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
      
        // getting data from our array list in our modal class.
        UserModal userModal = userModalArrayList.get(position);
        
          // on the below line we are setting data to our text view.
        holder.firstNameTV.setText(userModal.getFirst_name());
        holder.lastNameTV.setText(userModal.getLast_name());
        holder.emailTV.setText(userModal.getEmail());
      
        // on below line we are loading our image from the URL 
        // in our image view using Picasso.
        Picasso.get().load(userModal.getAvatar()).into(holder.userIV);
    }

    @Override
    public int getItemCount() {
        // returning the size of array list.
        return userModalArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
      
        // creating a variable for our text view and image view.
        private TextView firstNameTV, lastNameTV, emailTV;
        private ImageView userIV;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
          
            // initializing our variables.
            firstNameTV = itemView.findViewById(R.id.idTVFirstName);
            lastNameTV = itemView.findViewById(R.id.idTVLastName);
            emailTV = itemView.findViewById(R.id.idTVEmail);
            userIV = itemView.findViewById(R.id.idIVUser);
        }
    }
}
UserRVAdapter.kt
package org.geeksforgeeks.demo

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.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide;

class UserRVAdapter(
    private val userModalArrayList: ArrayList<UserModal>,
    private val context: Context
) : RecyclerView.Adapter<UserRVAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        
        // Inflating our layout file.
        val view = LayoutInflater.from(context).inflate(R.layout.items, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        
        // Getting data from our array
        // list in our modal class.
        val userModal = userModalArrayList[position]

        // Setting data to our text views.
        holder.firstNameTV.text = userModal.first_name
        holder.lastNameTV.text = userModal.last_name
        holder.emailTV.text = userModal.email

        Glide.with(context).load(userModal.avatar).into(holder.userIV)
    }

    override fun getItemCount(): Int {
    
        // Returning the size of the array list.
        return userModalArrayList.size
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    
        // Creating variables for our text
        // views and image view.
        val firstNameTV: TextView = itemView.findViewById(R.id.idTVFirstName)
        val lastNameTV: TextView = itemView.findViewById(R.id.idTVLastName)
        val emailTV: TextView = itemView.findViewById(R.id.idTVEmail)
        val userIV: ImageView = itemView.findViewById(R.id.idIVUser)
    }
}

 

Step 9: Creating a SheetRow

SheetRow is a new file created which will help us create new rows in the Application. Navigate to the app > Java/Kotlin > your app's package name > Right-click on it > New > Java/Kotlin class and name it as SheetRow and add the below code to it. 

SheetRow.java
package org.geeksforgeeks.demo;

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

public final class SheetRow {
    private final List<String> cells;

    public SheetRow(List<String> cells) {
        this.cells = cells;
    }

    public List<String> getCells() {
        return cells;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SheetRow sheetRow = (SheetRow) o;
        return Objects.equals(cells, sheetRow.cells);
    }

    @Override
    public int hashCode() {
        return Objects.hash(cells);
    }

    @Override
    public String toString() {
        return "SheetRow{" +
                "cells=" + cells +
                '}';
    }
}
SheetRow.kt
package org.geeksforgeeks.demo;

data class SheetRow(
    val cells: List<String>
)


Step 10: Working with MainActivity file

Go to the MainActivity file and refer to the following code. Below is the code for the MainActivity file. Comments are added inside the code to understand the code in more detail.

MainActivity.java
package org.geeksforgeeks.demo;

import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.firebase.FirebaseApp;
import com.google.firebase.database.FirebaseDatabase;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private Button fetchButton, uploadButton;
    private RecyclerView sheetRecyclerView;
    private UserRVAdapter userRVAdapter;
    private ArrayList<UserModal> userModalArrayList = new ArrayList<>();

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

        FirebaseApp.initializeApp(this);

        fetchButton = findViewById(R.id.fetchButton);
        uploadButton = findViewById(R.id.uploadButton);
        sheetRecyclerView = findViewById(R.id.sheetRecyclerView);

        userRVAdapter = new UserRVAdapter(userModalArrayList, this);
        sheetRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        sheetRecyclerView.setAdapter(userRVAdapter);

        fetchButton.setOnClickListener(v -> {
            String url = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQlLsJUKrUv22ulAXvBXLwT2rcMhSOKOS4BiIAPc-WZQTssJ5S0LeIWDwtgYW90fI-IZaE7sEOW1hVP/pub?output=csv";
            if (!url.isEmpty()) {
                new FetchSheetDataTask().execute(url);
            }
        });

        uploadButton.setOnClickListener(v -> {
            FirebaseDatabase.getInstance().getReference("users").setValue(userModalArrayList)
                .addOnSuccessListener(unused -> 
                    Toast.makeText(MainActivity.this, "Data uploaded successfully", Toast.LENGTH_SHORT).show()
                )
                .addOnFailureListener(e -> 
                    Toast.makeText(MainActivity.this, "Error uploading data: " + e.getMessage(), Toast.LENGTH_SHORT).show()
                );
        });
    }

    private class FetchSheetDataTask extends AsyncTask<String, Void, List<SheetRow>> {

        @Override
        protected List<SheetRow> doInBackground(String... urls) {
            List<SheetRow> rows = new ArrayList<>();
            try {
                String csvUrl = urls[0].replace("/edit#gid=", "/export?format=csv&gid=");
                BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(csvUrl).openStream()));
                String line;
                while ((line = reader.readLine()) != null) {
                    if (!line.trim().isEmpty()) {
                        List<String> cells = parseCSVLine(line);
                        rows.add(new SheetRow(cells));
                    }
                }
                reader.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return rows;
        }

        @Override
        protected void onPostExecute(List<SheetRow> rows) {
            super.onPostExecute(rows);

            if (rows.isEmpty()) {
                Toast.makeText(MainActivity.this, "No data found or error occurred.", Toast.LENGTH_SHORT).show();
                return;
            }

            userModalArrayList.clear();
            boolean skipHeader = true;

            for (SheetRow row : rows) {
                if (skipHeader) {
                    skipHeader = false;
                    continue;
                }

                if (row.getCells().size() >= 4) {
                    userModalArrayList.add(new UserModal(
                        row.getCells().get(0),
                        row.getCells().get(1),
                        row.getCells().get(2),
                        row.getCells().get(3)
                    ));
                }
            }

            userRVAdapter.notifyDataSetChanged();
        }
    }

    private List<String> parseCSVLine(String line) {
        List<String> result = new ArrayList<>();
        boolean inQuotes = false;
        StringBuilder cell = new StringBuilder();

        for (char c : line.toCharArray()) {
            if (c == '\"') {
                inQuotes = !inQuotes;
            } else if (c == ',' && !inQuotes) {
                result.add(cell.toString().trim());
                cell.setLength(0);
            } else {
                cell.append(c);
            }
        }

        result.add(cell.toString().trim()); // last cell
        return result;
    }
}
MainActivity.kt
package org.geeksforgeeks.demo

import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.FirebaseApp
import com.google.firebase.database.FirebaseDatabase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.net.URL

class MainActivity : AppCompatActivity() {
    private lateinit var fetchButton: Button
    private lateinit var uploadButton: Button
    private lateinit var sheetRecyclerView: RecyclerView

    // Use the new adapter
    private lateinit var userRVAdapter: UserRVAdapter

    // List to hold user data
    private val userModalArrayList = ArrayList<UserModal>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        FirebaseApp.initializeApp(this)

        fetchButton = findViewById(R.id.fetchButton)
        uploadButton = findViewById(R.id.uploadButton)
        sheetRecyclerView = findViewById(R.id.sheetRecyclerView)

        // Initialize the new adapter
        userRVAdapter = UserRVAdapter(userModalArrayList, this)
        sheetRecyclerView.layoutManager = LinearLayoutManager(this)

        // Set the new adapter
        sheetRecyclerView.adapter = userRVAdapter

        fetchButton.setOnClickListener {
            val url = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQlLsJUKrUv22ulAXvBXLwT2rcMhSOKOS4BiIAPc-WZQTssJ5S0LeIWDwtgYW90fI-IZaE7sEOW1hVP/pub?output=csv"
            if (url.isNotEmpty()) {
                fetchSheetData(url)
            }
        }

        uploadButton.setOnClickListener {
            val databaseRef = FirebaseDatabase.getInstance().getReference("users")

            databaseRef.setValue(userModalArrayList)
                .addOnSuccessListener {
                    // Data uploaded successfully
                    Toast.makeText(this, "Data uploaded successfully", Toast.LENGTH_SHORT).show()
                }
                .addOnFailureListener { e ->
                    // Handle errors
                    Toast.makeText(this, "Error uploading data: ${e.message}", Toast.LENGTH_SHORT).show()
                }
        }
    }

    private fun fetchSheetData(url: String) {
        CoroutineScope(Dispatchers.IO).launch {
            try {

                // Convert Google Sheets URL to CSV export URL
                val csvUrl = url.replace("/edit#gid=", "/export?format=csv&gid=")
                val response = URL(csvUrl).readText()
                val rows = parseCSV(response)

                // Clear the existing data
                userModalArrayList.clear()

                var flag=0

                // Convert CSV rows to UserModal objects
                for (row in rows) {
                    if(flag==0) {
                        flag=1;
                        continue;
                    }
                    if (row.cells.size >= 4) {

                        // Ensure the row has enough columns
                        val userModal = UserModal(
                            first_name = row.cells[0],
                            last_name = row.cells[1],
                            email = row.cells[2],
                            avatar = row.cells[3]
                        )
                        userModalArrayList.add(userModal)
                    }
                }

                // Update the adapter on the main thread
                withContext(Dispatchers.Main) {
                    userRVAdapter.notifyItemRangeChanged(0, userModalArrayList.size)
                    userRVAdapter.notifyDataSetChanged()
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {

                    // Handle errors (e.g., show a toast or log the error)
                    println("Error: ${e.message}")
                }
            }
        }
    }

    private fun parseCSV(csvData: String): List<SheetRow> {
        return csvData.split("\n")
            .filter { it.isNotBlank() }
            .map { row ->

                // Split by comma, but respect quoted values
                val cells = row.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)".toRegex())
                    .map { cell ->
                        cell.trim()
                            .removeSurrounding("\"")
                            .replace("\"\"", "\"")
                    }
                SheetRow(cells)
            }
    }
}


Output:



Next Article
Practice Tags :

Similar Reads