Search icon CANCEL
Subscription
0
Cart icon
Cart
Close icon
You have no products in your basket yet
Save more on your purchases!
Savings automatically calculated. No voucher code required
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering Firebase for Android Development

You're reading from  Mastering Firebase for Android Development

Product type Book
Published in Jun 2018
Publisher Packt
ISBN-13 9781788624718
Pages 394 pages
Edition 1st Edition
Languages
Author (1):
Ashok Kumar S Ashok Kumar S
Profile icon Ashok Kumar S
Toc

Table of Contents (23) Chapters close

Title Page
Copyright and Credits
Dedication
Packt Upsell
Contributors
Preface
1. Keep It Real – Firebase Realtime Database 2. Safe and Sound – Firebase Authentication 3. Safe and Sound – Firebase Crashlytics 4. Genie in the Cloud – Firebase Cloud Functions 5. Arsenal for Your Files – Firebase Cloud Storage 6. Not Just a Keeper, Firebase Hosting 7. Inspection and Evaluation – Firebase Test Lab 8. A Smart Watchdog – Firebase Performance Monitoring 9. Application Usage Measuring and Notification, Firebase Analytics, and Cloud Messaging 10. Changing Your App – Firebase Remote Config and Dynamic Links 11. Bringing Everyone on the Same Page, Firebase Invites, and Firebase App Indexing 12. Making a Monetary Impact and Firebase AdMob and AdWords 13. Flexible NoSQL and Cloud Firestore 14. Analytics Data, Clairvoyant, Firebase Predictions 15. Training Your Code and ML Kit 1. Other Books You May Enjoy Index

Creating an Android application using Realtime Database


We have explored all the possibilities of Realtime Database. Now let's build a small application using what we have learned. Ideating on the health and medical field is something that helps in the long term. In this project, we will build an Android mobile application that is crowdsourced to fetch email addresses of blood donors. 

User interface design

In this application, we will keep the user interface simple and informative. All we have is one RecyclerView and two buttons for adding and loading the data. The following xml layout code dictates the UI design: 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

    <TextView
android:textColor="@color/colorPrimaryDark"
android:textStyle="bold"
android:textSize="25dp"
android:gravity="center"
android:text="Packt Blood Bank"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
    <View
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="@color/colorAccent" />

The following code adds the vertical LinearLayout to support the DynamicData:

    <LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
        <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">

            <android.support.v7.widget.RecyclerView
android:id="@+id/peopleList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
        </LinearLayout>

The above code sets the dynamic lists that load the data from RecyclerView. lets continue updating the same layout to make the UI complete.  

        <View
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="@color/colorPrimary" />
        <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">

The following layout adds a scrollable layout for the input controls. 

            <ScrollView
android:scrollIndicators="right"
android:scrollbarStyle="insideOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical">
                <LinearLayout
android:layout_width="match_parent"
android:layout_height="150px"
android:layout_marginTop="40px"
android:gravity="center"
android:orientation="vertical">
                    <LinearLayout
android:layout_width="match_parent"
android:layout_height="150px"
android:layout_marginTop="40px"
android:gravity="center"
android:orientation="horizontal">
                        <EditText
android:id="@+id/donorNameInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Full name"
android:textColor="#000000"
android:textSize="16dp" />
                        <EditText
android:id="@+id/donorCityInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="City"
android:textColor="#000000" />
                    </LinearLayout>

The following code adds the donor blood group type and email address:

                    <LinearLayout
android:layout_width="match_parent"
android:layout_height="150px"
android:layout_marginTop="40px"
android:gravity="center"
android:orientation="horizontal">
                        <EditText
android:id="@+id/donorBloodGroupInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Blood Group"
android:textColor="#000000"
android:textSize="16dp" />
                    </LinearLayout>

                    <LinearLayout
android:layout_width="match_parent"
android:layout_height="150px"
android:layout_marginTop="40px"
android:gravity="center"
android:orientation="horizontal">

                        <EditText
android:id="@+id/donorEmailInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Email address"
android:textColor="#000000"
android:textSize="16dp" />

                    </LinearLayout>

The following code adds the buttons to act on the data received from the input fields:

                    <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#36FFFFFF">
                        <Button
android:id="@+id/loadBtn"
android:layout_width="500px"
android:layout_height="150px"
android:text="Load Donors info"
android:textColor="#000000"
android:textStyle="bold" />
                        <Button
android:id="@+id/addBtn"
android:layout_width="500px"
android:layout_height="150px"
android:layout_marginLeft="30px"
android:layout_toRightOf="@id/loadBtn"
android:text="Add Donor info"
android:textColor="#000000"
android:textStyle="bold" />
                    </RelativeLayout>
                </LinearLayout>
            </ScrollView>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

We also need each item layout for the RecyclerView, which is defined as follows. In this layout, all we have is four TextView:

<?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="wrap_content"
android:orientation="vertical">

    <TextView
android:id="@+id/donorName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:padding="10px"
android:textColor="@color/colorPrimary"
android:textSize="25dp"
android:textStyle="bold" />

    <TextView
android:id="@+id/donorCity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:padding="10px"
android:text="+216 54 821 200"
android:textSize="14dp"
android:textStyle="italic" />

    <TextView
android:id="@+id/donorBloodGroup"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:padding="10px"
android:text="+216 54 821 200"
android:textSize="14dp"
android:textStyle="italic" />

    <TextView
android:id="@+id/donorEmail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:padding="10px"
android:text="+216 54 821 200"
android:textSize="14dp"
android:textStyle="italic" />

</LinearLayout>

Now that we have our user interface in place, let's dive deep into the Java part. Let's create a class called Donor. This class is a Plain Old Java Object (POJO) class that we will use throughout the application, and the POJO class dictates the structure of the data. 

Logic

The following POJO class expresses the idea and the data format that we will save in Firebase. Using the POJO class we will pass the data to the adapter:

package com.ashok.packt.realtime.database.model;

/**
 * Created by ashok.kumar on 20/10/17.
 */
public class Donor {

private String FullName;
private String Email;
private String City;
private String BloodGroup;
public Donor(){

    }

Now within the same class lets create a constructor for passing the data to the POJO:

public Donor(String fullName, String email, String city, String bloodGroup) {
FullName = fullName;
Email = email;
City = city;
BloodGroup = bloodGroup;
    }

public String getFullName() {
return FullName;
    }

public void setFullName(String fullName) {
FullName = fullName;
    }

public String getEmail() {
return Email;
    }

public void setEmail(String email) {
Email = email;
    }

public String getCity() {
return City;
    }

public void setCity(String city) {
City = city;
    }

public String getBloodGroup() {
return BloodGroup;
    }

public void setBloodGroup(String bloodGroup) {
BloodGroup = bloodGroup;
    }
}

Now let's write our Adapter class. The Adapter class requires POJO, view holder, and row layout. Consider spending some time on understanding the RecyclerView adapter:

package com.ashok.packt.realtime.database.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.ashok.packt.realtime.database.R;
import com.ashok.packt.realtime.database.model.Donor;

import java.util.List;

/**
 * Created by ashok.kumar on 20/05/18.
 */

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.View_Holder>{

private Context mContext;
private List<Donor> ItemList;

public RecyclerViewAdapter(Context mContext, List<Donor> itemList) {
this.mContext = mContext;
ItemList = itemList;
    }

The constructors require context and the list of donor object for setting the data in RecyclerView callbacks. 

@Override
public View_Holder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.donor_list_row, parent, false);
return new View_Holder(itemView);
    }

The above Override method will be responsible for inflating the donor list item row. 

@Override
public void onBindViewHolder(View_Holder holder, int position) {

        Donor Item = ItemList.get(position);
        holder.Name.setText(Item.getFullName());
        holder.City.setText(Item.getCity());
        holder.BloodGroup.setText(Item.getBloodGroup());
        holder.Email.setText(Item.getEmail());

    }

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

public class View_Holder extends RecyclerView.ViewHolder {

        TextView Name;
        TextView City;
        TextView BloodGroup;
        TextView Phone;
        TextView Email;

        View_Holder(View itemView) {
super(itemView);

Name = (TextView) itemView.findViewById(R.id.donorName);
City = (TextView) itemView.findViewById(R.id.donorCity);
BloodGroup = (TextView) itemView.findViewById(R.id.donorBloodGroup);
Email = (TextView) itemView.findViewById(R.id.donorEmail);
        }
    }

}

Now, MainActivity holds the complete logic for the application by adding the data to Firebase, fetching the data from Firebase, and loading that in RecyclerView. I have also written methods to update, find, and delete for your future reference:

package com.ashok.packt.realtime.database;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

import com.ashok.packt.realtime.database.adapter.RecyclerViewAdapter;
import com.ashok.packt.realtime.database.model.Donor;
import com.google.firebase.database.ChildEventListener;
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.Query;
import com.google.firebase.database.ValueEventListener;

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

public class MainActivity extends AppCompatActivity {

private DatabaseReference myDatabaseReference;
private String personId;
private List<Donor> ItemList;
private RecyclerView mRecyclerview;
private RecyclerViewAdapter mAdapter;

Lets initialise all the above code in the onCreate method as shown below:

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

mRecyclerview = (RecyclerView) findViewById(R.id.peopleList);
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
mRecyclerview.setLayoutManager(mLayoutManager);

// for data persistence
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
myDatabaseReference=FirebaseDatabase.getInstance().getReference("Donor");
personId= myDatabaseReference.push().getKey();


        (findViewById(R.id.addBtn)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

                String FullName = ((EditText)findViewById(R.id.donorNameInput)).getText().toString();
                String Email = ((EditText)findViewById(R.id.donorEmailInput)).getText().toString();
                String City = ((EditText)findViewById(R.id.donorCityInput)).getText().toString();
                String BloodGroup = ((EditText)findViewById(R.id.donorBloodGroupInput)).getText().toString();


                addPerson(FullName,Email, City, BloodGroup);
            }
        });


        (findViewById(R.id.loadBtn)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
                readData();
            }
        });
    }

After adding the views its now time to work on the adding and retrieving the data as shown below:

private void addPerson(String name, String Email, String city, String Bloodgroup){
personId= myDatabaseReference.push().getKey();
Donor person = new Donor(name, Email, city, Bloodgroup);
myDatabaseReference.child(personId).setValue(person);
}

private void updatePerson(String name,int phoneNumber){
myDatabaseReference.child(personId).child("fullName").setValue(name);
myDatabaseReference.child(personId).child("phoneNumber").setValue(phoneNumber);
 }

private void removePerson(String name){
myDatabaseReference.child(personId).removeValue();
 }
private void readData(){
ItemList = new ArrayList<>();
myDatabaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
 Iterable<DataSnapshot> snapshotIterator = dataSnapshot.getChildren();
 Iterator<DataSnapshot> iterator = snapshotIterator.iterator();
while((iterator.hasNext())){
 Donor donor = iterator.next().getValue(Donor.class);
ItemList.add(donor);
mAdapter.notifyDataSetChanged();
 }
 }

@Override
public void onCancelled(DatabaseError databaseError) {

 }
 });

mAdapter = new RecyclerViewAdapter(this, ItemList);
mRecyclerview.setAdapter(mAdapter);

 }

We also can do the specific person search as shown below:

private void findPerson(String name){
 Query deleteQuery = myDatabaseReference.orderByChild("fullName").equalTo(name);
 deleteQuery.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
 Iterable<DataSnapshot> snapshotIterator = dataSnapshot.getChildren();
 Iterator<DataSnapshot> iterator = snapshotIterator.iterator();
while((iterator.hasNext())){
 Log.d("Item found: ",iterator.next().getValue().toString()+"---");
 }
 }

@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {

 }

@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {

 }

@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {

 }

@Override
public void onCancelled(DatabaseError databaseError) {
 Log.d("Item not found: ","this item is not in the list");
 }
 });
 }
}

When you compile and run the program in your Android device the output will have the following look and feel:

You have been reading a chapter from
Mastering Firebase for Android Development
Published in: Jun 2018 Publisher: Packt ISBN-13: 9781788624718
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime