Hire the author: Moses N
Image Source: Link
Introduction
My name is Moses N. I am a WordPress developer based in Kenya. Before I proceed, I know you are curious how come am a WordPress developer and am writing about Firebase, nevertheless, am currently venturing into android application development, and in this tutorial will be my pleasure to show you how to generate real-time reports using Firebase.
How to generate real-time reports using Firebase will be a continuation of How to create an android two-step authentication signup system using Firebase. So I would urge you to look at it before we continue. What will be actually doing in this tutorial is:
- Will be adding a button “Report” to our home activity.
- Button report will be used to save reports on our android phone and also display.
- iText Pdf Library will help us create PDF.
- Handle runtime permission.
- We will be retrieving information from the Firebase database.
- Will be designing our reports in a table format.
- Will be allowing write and read permission from our storage.
Get the complete project from GitHub
Enough intro? Let’s dig in now.
Photo Preview


Glossary
- Reports – A report is a document that presents information in an organized format for a specific audience and purpose.
- Firebase – is a Backend-as-a-Service (Baas) because It provides developers with a variety of tools. Also, services to help them develop quality apps, grow their user base, and earn a profit.
- Real-time – the actual time during which a process or event occurs.
In conclusion, I believe we are on the same page now. Therefore, let’s take our time to talk about the Project Requirement for Firebase Real-time Reports.
Firebase Real-time Reports project requirement.
- Android Phone – you will require your android phone to act as an emulator for running the project. Alternatively, you can download Memu. Also, you can install the emulator from your android studio.
- Editor – We will need an editor to write our codes with. You can go online and check out any text editors but I recommend we stick to Android Studio.
- Internet Connectivity – we will require the internet all through our project for installing dependencies and accessing Firebase Database.
- Git – This is kinda optional but I still recommend having git installed. This will prove useful if you ever want to deploy your code or push to a remote repository. You can download and install git through Git.
In short, that’s our project requirement. Let’s begin coding!
Steps to Firebase Real-time Reports:
Step 1: Adding Report Button.
Since we had designed our home activity in the previous blog we are going to change only a few things to make look at the photo preview below.

Below is the Home Activity code.
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout | |
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" | |
android:orientation="vertical" | |
tools:context=".MainActivity"> | |
<com.google.android.material.appbar.AppBarLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:theme="@style/AppTheme.AppBarOverlay"> | |
<androidx.appcompat.widget.Toolbar | |
android:id="@+id/main_toolbar" | |
android:layout_width="match_parent" | |
android:layout_height="?attr/actionBarSize" | |
android:background="?attr/colorPrimary" | |
app:popupTheme="@style/AppTheme.PopupOverlay" /> | |
</com.google.android.material.appbar.AppBarLayout> | |
<Button | |
android:id="@+id/button_disable_report" | |
android:layout_width="wrap_content" | |
android:layout_height="44dp" | |
android:layout_margin="8dp" | |
android:background="@drawable/button" | |
android:onClick="previewDisabledUsersReport" | |
android:padding="8dp" | |
android:text="@string/disabled_users_report" | |
android:textAllCaps="false" | |
style="?android:buttonBarButtonStyle" | |
android:textColor="@android:color/white" | |
android:textSize="14sp" /> | |
<com.github.barteksc.pdfviewer.PDFView | |
android:id="@+id/payment_pdf_viewer" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
/> | |
</LinearLayout> |
Step 2: Adding Firebase Real-time Reports Project dependencies.
We will be using the iText PDF Library to create PDF. You can get the library from here. To view the PDF we will need another library barteksc PDF viewer. You can get from here.
//for pdf
implementation 'com.itextpdf:itextg:5.5.10'
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
Step 3: Allowing Read and Write permission.

In order to save our PDF report in our phone storage, we will need to allow permission from the manifest. We will also allow handle runtime permission.
- Manifest permission.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- Handling runtime permission.
public static String[] PERMISSIONS = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
public static int PERMISSION_ALL = 12;
public boolean hasPermissions(Context context, String... permissions) {
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
public void previewDisabledUsersReport()
{
if (hasPermissions(this, PERMISSIONS)) {
DisplayReport();
} else {
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
}
Step 4: Creating setters and getters.
We are going to create a java class to hold all the setters and getters. The getters will enable us to retrieve data from the Firebase database and the setters will help set the retrieved data in the report.
package com.example.twostepauthentication; | |
public class Constants | |
{ | |
public String First_Name,Other_Name,Phone; | |
public String getFirst_Name() { | |
return First_Name; | |
} | |
public void setFirst_Name(String first_Name) { | |
First_Name = first_Name; | |
} | |
public String getOther_Name() { | |
return Other_Name; | |
} | |
public void setOther_Name(String other_Name) { | |
Other_Name = other_Name; | |
} | |
public String getPhone() { | |
return Phone; | |
} | |
public void setPhone(String phone) { | |
Phone = phone; | |
} | |
} |
Step 5: Creating the PDF report
Here we are going to create a method that will allow us to design the Firebase Real-time Reports. We will determine the number of columns it has from the data we are fetching from the database. We will also add a header and a footer. Now with that said let’s design the report to look like the image below.

private void createPaymentReport( List<Constants> paymentUsersList) throws DocumentException, FileNotFoundException{ | |
BaseColor colorWhite = WebColors.getRGBColor("#ffffff"); | |
BaseColor colorBlue = WebColors.getRGBColor("#056FAA"); | |
BaseColor grayColor = WebColors.getRGBColor("#425066"); | |
Font white = new Font(Font.FontFamily.HELVETICA, 15.0f, Font.BOLD, colorWhite); | |
FileOutputStream output = new FileOutputStream(pFile); | |
Document document = new Document(PageSize.A4); | |
PdfPTable table = new PdfPTable(new float[]{6, 25, 20, 20}); | |
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER); | |
table.getDefaultCell().setFixedHeight(50); | |
table.setTotalWidth(PageSize.A4.getWidth()); | |
table.setWidthPercentage(100); | |
table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE); | |
Chunk noText = new Chunk("No.", white); | |
PdfPCell noCell = new PdfPCell(new Phrase(noText)); | |
noCell.setFixedHeight(50); | |
noCell.setHorizontalAlignment(Element.ALIGN_CENTER); | |
noCell.setVerticalAlignment(Element.ALIGN_CENTER); | |
Chunk nameText = new Chunk("First Name", white); | |
PdfPCell nameCell = new PdfPCell(new Phrase(nameText)); | |
nameCell.setFixedHeight(50); | |
nameCell.setHorizontalAlignment(Element.ALIGN_CENTER); | |
nameCell.setVerticalAlignment(Element.ALIGN_CENTER); | |
Chunk phoneText = new Chunk("Other Names", white); | |
PdfPCell phoneCell = new PdfPCell(new Phrase(phoneText)); | |
phoneCell.setFixedHeight(50); | |
phoneCell.setHorizontalAlignment(Element.ALIGN_CENTER); | |
phoneCell.setVerticalAlignment(Element.ALIGN_CENTER); | |
Chunk amountText = new Chunk("Phone Number", white); | |
PdfPCell amountCell = new PdfPCell(new Phrase(amountText)); | |
amountCell.setFixedHeight(50); | |
amountCell.setHorizontalAlignment(Element.ALIGN_CENTER); | |
amountCell.setVerticalAlignment(Element.ALIGN_CENTER); | |
Chunk footerText = new Chunk("Moses Njoroge - Copyright @ 2020"); | |
PdfPCell footCell = new PdfPCell(new Phrase(footerText)); | |
footCell.setFixedHeight(70); | |
footCell.setHorizontalAlignment(Element.ALIGN_CENTER); | |
footCell.setVerticalAlignment(Element.ALIGN_CENTER); | |
footCell.setColspan(4); | |
table.addCell(noCell); | |
table.addCell(nameCell); | |
table.addCell(phoneCell); | |
table.addCell(amountCell); | |
table.setHeaderRows(1); | |
PdfPCell[] cells = table.getRow(0).getCells(); | |
for (PdfPCell cell : cells) { | |
cell.setBackgroundColor(grayColor); | |
} | |
for (int i = 0; i < paymentUsersList.size(); i++) { | |
Constants pay = paymentUsersList.get(i); | |
String id = String.valueOf(i + 1); | |
String name = pay.getFirst_Name(); | |
String sname = pay.getOther_Name(); | |
String phone = pay.getPhone(); | |
table.addCell(id + ". "); | |
table.addCell(name); | |
table.addCell(sname); | |
table.addCell(phone); | |
} | |
PdfPTable footTable = new PdfPTable(new float[]{6, 25, 20, 20}); | |
footTable.setTotalWidth(PageSize.A4.getWidth()); | |
footTable.setWidthPercentage(100); | |
footTable.addCell(footCell); | |
PdfWriter.getInstance(document, output); | |
document.open(); | |
Font g = new Font(Font.FontFamily.HELVETICA, 25.0f, Font.NORMAL, grayColor); | |
document.add(new Paragraph(" How to generate real-time reports using Firebase\n\n", g)); | |
document.add(table); | |
document.add(footTable); | |
document.close(); | |
} |
Step 6: Fetching data from Firebase.
In this stage, we will fetch data from the Firebase database using getters. Then we will display the data fetched in the report using setters.
//function to fetch payment data from the database | |
private void fetchPaymentUsers() | |
{ | |
payRef.addValueEventListener(new ValueEventListener() { | |
@Override | |
public void onDataChange(DataSnapshot dataSnapshot) { | |
for (DataSnapshot snapshot : dataSnapshot.getChildren()) { | |
//creating an object and setting to displlay | |
Constants pays = new Constants(); | |
pays.setFirst_Name(snapshot.child("FirstName").getValue().toString()); | |
pays.setOther_Name(snapshot.child("OtherName").getValue().toString()); | |
pays.setPhone(snapshot.child("Phone").getValue().toString()); | |
//this just log details fetched from db(you can use Timber for logging | |
Log.d("Payment", "Name: " + pays.getFirst_Name()); | |
Log.d("Payment", "othername: " + pays.getOther_Name()); | |
Log.d("Payment", "phone: " + pays.getPhone()); | |
/* The error before was cause by giving incorrect data type | |
You were adding an object of type PaymentUsers yet the arraylist expects obejct of type DisabledUsers | |
*/ | |
paymentUsersList.add(pays); | |
} | |
//create a pdf file and catch exception beacause file may not be created | |
try { | |
createPaymentReport(paymentUsersList); | |
} catch (DocumentException | FileNotFoundException e) { | |
e.printStackTrace(); | |
} | |
} | |
@Override | |
public void onCancelled(DatabaseError databaseError) { | |
} | |
}); | |
} |
Finally, we will save the report in internal storage.
paymentUsersList = new ArrayList<>(); | |
//create files in reports care folder | |
payfile = new File("/storage/emulated/0/Report/"); | |
//check if they exist, if not create them(directory) | |
if ( !payfile.exists()) { | |
payfile.mkdirs(); | |
} | |
pFile = new File(payfile, "PaymentUsers.pdf"); | |
fetchPaymentUsers(); | |
} |
Step 7:Display report.
Finally lets display the report on click or the report button.
private void DisplayReport() | |
{ | |
pdfView.fromFile(pFile) | |
.pages(0,2,1,3,3,3) | |
.enableSwipe(true) | |
.swipeHorizontal(false) | |
.enableDoubletap(true) | |
.defaultPage(0) | |
.load(); | |
} | |
Button reportButton = findViewById(R.id.button_disable_report); | |
reportButton.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
previewDisabledUsersReport(); | |
} | |
}); |
full code for the main activity
package com.example.twostepauthentication; | |
import androidx.annotation.NonNull; | |
import androidx.appcompat.app.AppCompatActivity; | |
import androidx.appcompat.widget.Toolbar; | |
import androidx.core.app.ActivityCompat; | |
import androidx.fragment.app.FragmentTransaction; | |
import android.Manifest; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.content.pm.PackageManager; | |
import android.os.Bundle; | |
import android.util.Log; | |
import android.view.View; | |
import android.widget.Button; | |
import com.github.barteksc.pdfviewer.PDFView; | |
import com.google.firebase.auth.FirebaseAuth; | |
import com.google.firebase.auth.FirebaseUser; | |
import com.google.firebase.database.DataSnapshot; | |
import com.google.firebase.database.DatabaseError; | |
import com.google.firebase.database.DatabaseReference; | |
import com.google.firebase.database.FirebaseDatabase; | |
import com.google.firebase.database.ValueEventListener; | |
import com.itextpdf.text.BaseColor; | |
import com.itextpdf.text.Chunk; | |
import com.itextpdf.text.Document; | |
import com.itextpdf.text.DocumentException; | |
import com.itextpdf.text.Element; | |
import com.itextpdf.text.Font; | |
import com.itextpdf.text.PageSize; | |
import com.itextpdf.text.Paragraph; | |
import com.itextpdf.text.Phrase; | |
import com.itextpdf.text.html.WebColors; | |
import com.itextpdf.text.pdf.PdfPCell; | |
import com.itextpdf.text.pdf.PdfPTable; | |
import com.itextpdf.text.pdf.PdfWriter; | |
import java.io.File; | |
import java.io.FileNotFoundException; | |
import java.io.FileOutputStream; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class MainActivity extends AppCompatActivity { | |
//firebase auth to check if user is authenticated. | |
private FirebaseAuth mAuth; | |
private DatabaseReference userRef; | |
private DatabaseReference payRef; | |
//creating a list of objects constants | |
List<Constants> paymentUsersList; | |
//List all permission required | |
public static String[] PERMISSIONS = { | |
Manifest.permission.READ_EXTERNAL_STORAGE, | |
Manifest.permission.WRITE_EXTERNAL_STORAGE | |
}; | |
public static int PERMISSION_ALL = 12; | |
public static File pFile; | |
private File payfile; | |
private PDFView pdfView; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
Toolbar toolbar = findViewById(R.id.main_toolbar); | |
setSupportActionBar(toolbar); | |
getSupportActionBar().setTitle("Home"); | |
mAuth = FirebaseAuth.getInstance(); | |
userRef = FirebaseDatabase.getInstance().getReference().child("Users"); | |
payRef = FirebaseDatabase.getInstance().getReference().child("Users"); | |
pdfView = findViewById(R.id.payment_pdf_viewer); | |
Button reportButton = findViewById(R.id.button_disable_report); | |
reportButton.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
previewDisabledUsersReport(); | |
} | |
}); | |
// | |
paymentUsersList = new ArrayList<>(); | |
//create files in charity care folder | |
payfile = new File("/storage/emulated/0/Report/"); | |
//check if they exist, if not create them(directory) | |
if ( !payfile.exists()) { | |
payfile.mkdirs(); | |
} | |
pFile = new File(payfile, "PaymentUsers.pdf"); | |
//fetch payment and disabled users details; | |
fetchPaymentUsers(); | |
} | |
//function to fetch payment data from the database | |
private void fetchPaymentUsers() | |
{ | |
payRef.addValueEventListener(new ValueEventListener() { | |
@Override | |
public void onDataChange(DataSnapshot dataSnapshot) { | |
for (DataSnapshot snapshot : dataSnapshot.getChildren()) { | |
//creating an object and setting to displlay | |
Constants pays = new Constants(); | |
pays.setFirst_Name(snapshot.child("FirstName").getValue().toString()); | |
pays.setOther_Name(snapshot.child("OtherName").getValue().toString()); | |
pays.setPhone(snapshot.child("Phone").getValue().toString()); | |
//this just log details fetched from db(you can use Timber for logging | |
Log.d("Payment", "Name: " + pays.getFirst_Name()); | |
Log.d("Payment", "othername: " + pays.getOther_Name()); | |
Log.d("Payment", "phone: " + pays.getPhone()); | |
/* The error before was cause by giving incorrect data type | |
You were adding an object of type PaymentUsers yet the arraylist expects obejct of type DisabledUsers | |
*/ | |
paymentUsersList.add(pays); | |
} | |
//create a pdf file and catch exception beacause file may not be created | |
try { | |
createPaymentReport(paymentUsersList); | |
} catch (DocumentException | FileNotFoundException e) { | |
e.printStackTrace(); | |
} | |
} | |
@Override | |
public void onCancelled(DatabaseError databaseError) { | |
} | |
}); | |
} | |
private void createPaymentReport( List<Constants> paymentUsersList) throws DocumentException, FileNotFoundException{ | |
BaseColor colorWhite = WebColors.getRGBColor("#ffffff"); | |
BaseColor colorBlue = WebColors.getRGBColor("#056FAA"); | |
BaseColor grayColor = WebColors.getRGBColor("#425066"); | |
Font white = new Font(Font.FontFamily.HELVETICA, 15.0f, Font.BOLD, colorWhite); | |
FileOutputStream output = new FileOutputStream(pFile); | |
Document document = new Document(PageSize.A4); | |
PdfPTable table = new PdfPTable(new float[]{6, 25, 20, 20}); | |
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER); | |
table.getDefaultCell().setFixedHeight(50); | |
table.setTotalWidth(PageSize.A4.getWidth()); | |
table.setWidthPercentage(100); | |
table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE); | |
Chunk noText = new Chunk("No.", white); | |
PdfPCell noCell = new PdfPCell(new Phrase(noText)); | |
noCell.setFixedHeight(50); | |
noCell.setHorizontalAlignment(Element.ALIGN_CENTER); | |
noCell.setVerticalAlignment(Element.ALIGN_CENTER); | |
Chunk nameText = new Chunk("First Name", white); | |
PdfPCell nameCell = new PdfPCell(new Phrase(nameText)); | |
nameCell.setFixedHeight(50); | |
nameCell.setHorizontalAlignment(Element.ALIGN_CENTER); | |
nameCell.setVerticalAlignment(Element.ALIGN_CENTER); | |
Chunk phoneText = new Chunk("Other Names", white); | |
PdfPCell phoneCell = new PdfPCell(new Phrase(phoneText)); | |
phoneCell.setFixedHeight(50); | |
phoneCell.setHorizontalAlignment(Element.ALIGN_CENTER); | |
phoneCell.setVerticalAlignment(Element.ALIGN_CENTER); | |
Chunk amountText = new Chunk("Phone Number", white); | |
PdfPCell amountCell = new PdfPCell(new Phrase(amountText)); | |
amountCell.setFixedHeight(50); | |
amountCell.setHorizontalAlignment(Element.ALIGN_CENTER); | |
amountCell.setVerticalAlignment(Element.ALIGN_CENTER); | |
Chunk footerText = new Chunk("Moses Njoroge - Copyright @ 2020"); | |
PdfPCell footCell = new PdfPCell(new Phrase(footerText)); | |
footCell.setFixedHeight(70); | |
footCell.setHorizontalAlignment(Element.ALIGN_CENTER); | |
footCell.setVerticalAlignment(Element.ALIGN_CENTER); | |
footCell.setColspan(4); | |
table.addCell(noCell); | |
table.addCell(nameCell); | |
table.addCell(phoneCell); | |
table.addCell(amountCell); | |
table.setHeaderRows(1); | |
PdfPCell[] cells = table.getRow(0).getCells(); | |
for (PdfPCell cell : cells) { | |
cell.setBackgroundColor(grayColor); | |
} | |
for (int i = 0; i < paymentUsersList.size(); i++) { | |
Constants pay = paymentUsersList.get(i); | |
String id = String.valueOf(i + 1); | |
String name = pay.getFirst_Name(); | |
String sname = pay.getOther_Name(); | |
String phone = pay.getPhone(); | |
table.addCell(id + ". "); | |
table.addCell(name); | |
table.addCell(sname); | |
table.addCell(phone); | |
} | |
PdfPTable footTable = new PdfPTable(new float[]{6, 25, 20, 20}); | |
footTable.setTotalWidth(PageSize.A4.getWidth()); | |
footTable.setWidthPercentage(100); | |
footTable.addCell(footCell); | |
PdfWriter.getInstance(document, output); | |
document.open(); | |
Font g = new Font(Font.FontFamily.HELVETICA, 25.0f, Font.NORMAL, grayColor); | |
document.add(new Paragraph(" How to generate real-time reports using Firebase\n\n", g)); | |
document.add(table); | |
document.add(footTable); | |
document.close(); | |
} | |
public boolean hasPermissions(Context context, String... permissions) { | |
if (context != null && permissions != null) { | |
for (String permission : permissions) { | |
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { | |
return false; | |
} | |
} | |
} | |
return true; | |
} | |
//onstart method used to check if the user is registered or not | |
@Override | |
protected void onStart() | |
{ | |
super.onStart(); | |
FirebaseUser currentUser = mAuth.getCurrentUser(); | |
if (currentUser ==null){ | |
SendUserToLoginActivity(); | |
} | |
else{ | |
//checking if the user exists in the firebase database | |
CheckUserExistence(); | |
} | |
} | |
private void CheckUserExistence() | |
{ | |
//get the user id | |
final String currentUserId = mAuth.getCurrentUser().getUid(); | |
userRef.addValueEventListener(new ValueEventListener() { | |
@Override | |
public void onDataChange(@NonNull DataSnapshot dataSnapshot) | |
{ | |
if (!dataSnapshot.hasChild(currentUserId)){ | |
//user is authenticated but but his record is not present in real time firebase database | |
SendUserToStepTwoAuthentication(); | |
} | |
} | |
@Override | |
public void onCancelled(@NonNull DatabaseError databaseError) { | |
} | |
}); | |
} | |
private void SendUserToStepTwoAuthentication() | |
{ | |
Intent steptwoIntent = new Intent(MainActivity.this, StepTwoAuthentication.class); | |
steptwoIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); | |
startActivity(steptwoIntent); | |
finish(); | |
} | |
private void SendUserToLoginActivity() | |
{ | |
Intent loginIntent = new Intent(MainActivity.this, Login.class); | |
loginIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); | |
startActivity(loginIntent); | |
finish(); | |
} | |
public void previewDisabledUsersReport() | |
{ | |
if (hasPermissions(this, PERMISSIONS)) { | |
DisplayReport(); | |
} else { | |
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL); | |
} | |
} | |
private void DisplayReport() | |
{ | |
pdfView.fromFile(pFile) | |
.pages(0,2,1,3,3,3) | |
.enableSwipe(true) | |
.swipeHorizontal(false) | |
.enableDoubletap(true) | |
.defaultPage(0) | |
.load(); | |
} | |
} |
By this, we have completed our tutorial on how to generate real-time reports using Firebase. Click on the Run button and Run the application on your android phone but you can also install an android emulator on the android studio.
Reflective Analysis
It was a simple project for me, but I was still able to gain some deeper insights into Firebase and programming in general. Working with imported dependencies was a challenge but managed to fix by visiting stack overflow and you-tube tutorials.
Future Directions
In order to get more knowledge about Firebase Real-time Reports, I recommend that you add more rows and columns in the report. You can try using different fonts and changing the color of the report to your choice. You can also try to generate reports using SQLite.
Learning Strategies and Tools
There are a lot of learning tools online, I would recommend the following:
I used the learning tools above to create Firebase Real-time Reports. I also used PDF documentations to achieve this. Anytime I faced some bugs, I would use stack overflow to check for solutions.
It took me a total of 9 hours to finish the project and the blog.
Conclusion
In conclusion, this project mainly focuses on how to generate real-time reports using Firebase. Reports are very important in each and every organization for many reasons. I, therefore, find this project very useful. . I hope you have learned a lot from this lesson. Therefore, I will be looking forward to seeing you build something great.
Get the complete project from GitHub
Happy Coding!
Moses, this is a very nice blog and really helpful. I love the way you have kept it simple and clear. The code has comments making it understandable and am glad its working fine.
I really do agree with you that reports are very useful in each and every organization, Be it a small or large enterprise. Been in a position to generate reports using android phone is really great and reliable. I believe this where current technology is heading to rather that using web based systems.
The future directions of this project is to generate same reports using other languages such a Python and also using different databases like SQLite rather than Firebase.
Good work!
This Article was referenced in How to auto generate a report from firebase database
it doesn’t work even when i use the file from github pdf it won’t appear and i am using android 10
Thank you so much sir. this is exactly same as i wan it for my project. It helped me a lot. thank you so much.