Sun. Jan 20th, 2019

Android Firebase working with Realtime Database and Storage

Firebase|Firebase is the cloud service provides Google that gives us the tools and infrastructure to build better App quickly.It is available for various platform like Android, Web, Ios.It provides Realtime Database, Cloud Messaging, Storage etc.In this tutorial, we will learn how to add data into Real-time Database and storage and retrieve from them and show in a recyclerview.We also learn how to enable Firebase Offline Capabilities.Firebase Offline Capabilities is a tool which provides persisting data locally, managing presence, and handling latency.It’s mean if your app temporarily loses its network connection Firebase Application will work normally.

Download Project – Here

Download APK –Apk

Creating a new Project:-

Open your Android Studio & create a new Project, have taken BasicActivity for this project and clicked finish.

Pre-Requisites:-

For Integrating Firebase into your App you need to create and register your app in Firebase Console.

Create a new project.It looks like

Then click on Add Firebase to your Android app.

After the click pops up a window and asked for the package name.You put your own package name.

After register your app you need to download JSON file.

After downloading the JSON file you need to copy the file and paste into app folder.

build.gradle project level file:

Open your build.gradle project level file and add the following line

dependencies {
   ................................................
    classpath 'com.google.gms:google-services:3.1.0'

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}

build.gradle app level file:-

In this project, we are going to use Firebase database, storage, offline capability, recyclerview, cardview.So we have to add all dependencies.So add the following lines to your build.gradle app level file

dependencies {
    ..........................................
    ..........................................
    compile 'com.android.support:design:25.3.1'
    compile 'com.google.firebase:firebase-database:10.2.6'
    compile 'com.firebaseui:firebase-ui-database:1.1.1'
    compile 'com.android.support:recyclerview-v7:25.3.1'
    compile 'com.android.support:cardview-v7:25.3.1'
    compile 'com.google.firebase:firebase-storage:10.2.6'
    compile 'de.hdodenhof:circleimageview:2.1.0'
    compile 'com.squareup.picasso:picasso:2.5.2'
    compile 'com.squareup.okhttp:okhttp:2.4.0'
    .........................................
}

We create another activity named AddConact.java.This activity is for additional information into the database.

Creating Layout:-

activity_add_contact.XML :-

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/activity_add_contact"
    tools:context="com.example.rubs.firebase.AddContact">

    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:scaleType="centerCrop"
        android:layout_marginTop="41dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/imageSelect"
        android:src="@mipmap/ic_account_circle_black_24dp"/>

    <EditText
        android:id="@+id/nameField"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="61dp"
        android:ems="10"
        android:hint="Name"
        android:inputType="textPersonName"
        android:layout_below="@+id/imageSelect"
        android:layout_alignParentStart="true" />

    <EditText
        android:id="@+id/addressField"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignStart="@+id/nameField"
        android:layout_below="@+id/nameField"
        android:layout_marginTop="24dp"
        android:ems="10"
        android:hint="Address"
        android:inputType="textPersonName" />

    <Button
        android:id="@+id/addContactBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@color/colorPrimary"
        android:text="Add Contact"
        android:textColor="#FFFFFF" />

</RelativeLayout>

Here we have a circular image view, two edit texts- one is for the name and other is for address and an Add Contact button for add contact into the database.

AddContact.java

import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
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.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.OnProgressListener;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;

public class AddContact extends AppCompatActivity {
    private ImageView mSelectImage;
    private EditText mContactName;
    private EditText mContactAddress;
    private Button mSubmitBtn;
    private Uri mImageUri = null;
    private ProgressDialog mProgress;
    private StorageReference mStorage;
    private DatabaseReference mDatabase;
    private static final int GALLERY_REQUEST = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_contact);
        mContactName = (EditText)findViewById(R.id.nameField);
        mContactAddress = (EditText) findViewById(R.id.addressField);
        mSubmitBtn = (Button) findViewById(R.id.addContactBtn);
        mSelectImage = (ImageView) findViewById(R.id.imageSelect);
        mProgress = new ProgressDialog(this);
        mStorage = FirebaseStorage.getInstance().getReference();
        mDatabase = FirebaseDatabase.getInstance().getReference().child("Contact");
        mSelectImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                galleryIntent.setType("image/*");
                startActivityForResult(galleryIntent, GALLERY_REQUEST);
            }
        });
        mSubmitBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startAdding();
            }
        });
    }
    private void startAdding() {
        final String name_val = mContactName.getText().toString().trim();
        final String address_val = mContactAddress.getText().toString().trim();
        if (!TextUtils.isEmpty(name_val) && !TextUtils.isEmpty(address_val) && mImageUri != null){
            mProgress.setTitle("Adding contact...");
            mProgress.show();
            StorageReference filepath = mStorage.child("Contact_Images").child(mImageUri.getLastPathSegment());
            filepath.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    final Uri downloadUri = taskSnapshot.getDownloadUrl();
                    final  DatabaseReference newPost = mDatabase.push();
                    mDatabase.addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            newPost.child("name").setValue(name_val);
                            newPost.child("address").setValue(address_val);
                            newPost.child("image").setValue(downloadUri.toString()).addOnCompleteListener(new OnCompleteListener<Void>() {
                                @Override
                                public void onComplete(@NonNull Task<Void> task) {
                                    if(task.isSuccessful()){
                                        startActivity(new Intent(AddContact.this, MainActivity.class));
                                    }
                                }
                            });
                        }
                        @Override
                        public void onCancelled(DatabaseError databaseError) {
                        }
                    });
                    mProgress.dismiss();
                    Toast.makeText(getApplicationContext(), " Adding Complete!! ", Toast.LENGTH_SHORT).show();
                }
            }).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                    double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
                    mProgress.setMessage("Uploaded" + ((int) progress) + "%...");
                }
            });
        }else{
            Toast.makeText(getApplicationContext(), "Failed... ", Toast.LENGTH_SHORT).show();
        }
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == GALLERY_REQUEST && resultCode == RESULT_OK && data!= null){
            mImageUri = data.getData();
            mSelectImage.setImageURI(mImageUri);
        }
    }
}

We declare all views of the XML file and set imageview as a clicklistener for taking an image from the gallery.

@Override
public void onClick(View v) {
    Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    galleryIntent.setType("image/*");
    startActivityForResult(galleryIntent, GALLERY_REQUEST);
}

and set image by creating an onActivityResult method

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == GALLERY_REQUEST && resultCode == RESULT_OK && data!= null){
        mImageUri = data.getData();
        mSelectImage.setImageURI(mImageUri);
    }
}

To add data to the database we have created startAdding() method.

private void startAdding() {
    final String name_val = mContactName.getText().toString().trim();
    final String address_val = mContactAddress.getText().toString().trim();
    if (!TextUtils.isEmpty(name_val) && !TextUtils.isEmpty(address_val) && mImageUri != null){
        mProgress.setTitle("Adding contact...");
        mProgress.show();
        StorageReference filepath = mStorage.child("Contact_Images").child(mImageUri.getLastPathSegment());
        filepath.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                final Uri downloadUri = taskSnapshot.getDownloadUrl();
                final  DatabaseReference newPost = mDatabase.push();
                mDatabase.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        newPost.child("name").setValue(name_val);
                        newPost.child("address").setValue(address_val);
                        newPost.child("image").setValue(downloadUri.toString()).addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                if(task.isSuccessful()){
                                    startActivity(new Intent(AddContact.this, MainActivity.class));
                                }
                            }
                        });
                    }
                    @Override
                    public void onCancelled(DatabaseError databaseError) {
                    }
                });
                mProgress.dismiss();
                Toast.makeText(getApplicationContext(), " Adding Complete!! ", Toast.LENGTH_SHORT).show();
            }
        });
    }else{
        Toast.makeText(getApplicationContext(), "Failed... ", Toast.LENGTH_SHORT).show();
    }
}

At first, we have taken database reference and storage reference

private StorageReference mStorage;
private DatabaseReference mDatabase;

In database, we need to create a branch to store data (like table) so we created Contact branch by

mDatabase = FirebaseDatabase.getInstance().getReference().child("Contact");

We need to store images into Firebase Storage. Here we also create a file to store images by

StorageReference filepath = mStorage.child("Contact_Images").child(mImageUri.getLastPathSegment());

.Child() is a method by which we can create a number of sub-branches.

.Push() is the method for add data into a database.

Add data to the database with different sub-branch we override onDataChange method.This method will call when we add some data to the database.And we create three sub-branch(like the table) for the name, address, and image.We can’t directly add a picture to the database.So we only put the URL of the picture which is saved in Firebase Storage.

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
    newPost.child("name").setValue(name_val);
    newPost.child("address").setValue(address_val);
    newPost.child("image").setValue(downloadUri.toString()).addOnCompleteListener(new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
            if(task.isSuccessful()){
                startActivity(new Intent(AddContact.this, MainActivity.class));
            }
        }
    });
}

This is the architecture of the Database.

Related:

Android Real Time Face detection and Prediction using Google Mobile Vision API

Android Realm database in Android(Insert & retrieve data from database)

Upload image from gallery to firebase in Android

Insert and retrieve data using Android ORMLite database

Display current location(latitude and longitude) in google map and save it to the Firebase database in Android

Note:-

Don’t forget to change the rules of Firebase Database and Storage.If you add Firebase Authentication in your project don’t need to change the default rules.But if you are not used you must change the rules otherwise Firebase will not allow to read or write in Database as well as Storage and maybe your app will be crashed.Your rules something look like –

 

 

 

 

 

 

 

 

For the database, you have to change 3rd and 4th line (read and write “true”) and for storage, you have to change only 4th line(request.auth == null;).

Creating Layout:-

activity_main.xml :-

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.rubs.firebase.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_add_black_24dp" />

</android.support.design.widget.CoordinatorLayout>

This is auto-generated code.When we choose Basic Activity it will automatically be generated.

Creating Layout:-

contain_main.xml :-

It is also auto-generated XML file

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.rubs.firebase.MainActivity"
    tools:showIn="@layout/activity_main">

    <android.support.v7.widget.RecyclerView
        android:layout_width="368dp"
        android:layout_height="495dp"
        android:id="@+id/contact_list"
        tools:layout_editor_absoluteY="8dp"
        tools:layout_editor_absoluteX="8dp">
    </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

We only add a recyclerview to display our information.

Creating Card Layout:-

contact_row.xml :-

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="80dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_margin="8dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:orientation="horizontal">
            <de.hdodenhof.circleimageview.CircleImageView
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:src="@mipmap/ic_account_circle_black_24dp"
                android:id="@+id/contact_image"/>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:layout_marginLeft="16dp"
                android:gravity="center_vertical"
                android:orientation="vertical">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
                  <TextView
                      android:layout_width="0dp"
                      android:layout_height="wrap_content"
                      android:layout_weight="1"
                      android:maxLines="1"
                      android:id="@+id/contact_name"
                      android:text="Name"
                      android:textColor="@android:color/black"
                      android:textStyle="bold"/>
                </LinearLayout>
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Address"
                    android:id="@+id/contact_address"/>
            </LinearLayout>

        </LinearLayout>

    </LinearLayout>

</android.support.v7.widget.CardView>

We want to display our information on a single card so we created a cardView and set an id for this.

Creating a Java Class -> Contact.java

public class Contact {
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    private String name;
    private String address;
    private String image;
    public Contact(){

    }
    public Contact(String name, String address, String image) {
        this.name = name;
        this.address = address;
        this.image = image;
    }
}

We declare name, address, image as a private string and generate getter and setter method.Also, create a constructor for name address and image.

MainActivity.Java

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.squareup.picasso.Callback;
import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;

public class MainActivity extends AppCompatActivity {
    private RecyclerView mContactList;
    private DatabaseReference mDatabase;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDatabase = FirebaseDatabase.getInstance().getReference().child("Contact");
        mDatabase.keepSynced(true);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        mContactList = (RecyclerView)findViewById(R.id.contact_list);
        mContactList.setHasFixedSize(true);
        mContactList.setLayoutManager(new LinearLayoutManager(this));
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              /*  Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();  */
                startActivity(new Intent(MainActivity.this, AddContact.class));
            }
        });
    }
    @Override
    protected void onStart() {
        super.onStart();
        FirebaseRecyclerAdapter<Contact, ContactViewHolder > firebaseRecyclerAdapter =
                new FirebaseRecyclerAdapter<Contact, ContactViewHolder>(
                        Contact.class,
                        R.layout.contact_row,
                        ContactViewHolder.class,
                        mDatabase
                ) {
                    @Override
                    protected void populateViewHolder(ContactViewHolder viewHolder, Contact model, int position) {
                        viewHolder.setName(model.getName());
                        viewHolder.setAddress(model.getAddress());
                        viewHolder.setImage(getApplicationContext(), model.getImage());
                    }
                };
        mContactList.setAdapter(firebaseRecyclerAdapter);
    }
    public static class ContactViewHolder extends RecyclerView.ViewHolder{
        View mView;
        public ContactViewHolder(View itemView) {
            super(itemView);
            mView = itemView;
        }
        public void setName(String name){
            TextView contact_name = (TextView)mView.findViewById(R.id.contact_name);
            contact_name.setText(name);
        }
        public void setAddress(String address){
            TextView contact_address = (TextView)mView.findViewById(R.id.contact_address);
            contact_address.setText(address);
        }
        public void setImage(final Context ctx, final String image){
            final ImageView contact_image = (ImageView)mView.findViewById(R.id.contact_image);
            Picasso.with(ctx).load(image).networkPolicy(NetworkPolicy.OFFLINE).into(contact_image, new Callback() {
                @Override
                public void onSuccess() {
                }
                @Override
                public void onError() {
                    Picasso.with(ctx).load(image).into(contact_image);
                }
            });
        }
    }
}

We declare our recyclerview and take reference for our database which we want to access.

mDatabase = FirebaseDatabase.getInstance().getReference().child("Contact");
mDatabase.keepSynced(true);
mContactList = (RecyclerView)findViewById(R.id.contact_list);

.keepSynced() is a method that is the response the data changed into Database.

We create a ContactViewHolder method.BY this method we get our all information from the database.And for images, we have used Picasso image loader and set to also offline mode.

public static class ContactViewHolder extends RecyclerView.ViewHolder{
    View mView;
    public ContactViewHolder(View itemView) {
        super(itemView);
        mView = itemView;
    }
    public void setName(String name){
        TextView contact_name = (TextView)mView.findViewById(R.id.contact_name);
        contact_name.setText(name);
    }
    public void setAddress(String address){
        TextView contact_address = (TextView)mView.findViewById(R.id.contact_address);
        contact_address.setText(address);
    }
    public void setImage(final Context ctx, final String image){
        final ImageView contact_image = (ImageView)mView.findViewById(R.id.contact_image);
        Picasso.with(ctx).load(image).networkPolicy(NetworkPolicy.OFFLINE).into(contact_image, new Callback() {
            @Override
            public void onSuccess() {
            }
            @Override
            public void onError() {
                Picasso.with(ctx).load(image).into(contact_image);
            }
        });
    }
}

We override onStart method and we used FirebaseRecyclerAdapter.This method is provided by Firebase UI.We set our cardview and also set name address and image into proper position by populateViewHolder method.

@Override
protected void onStart() {
    super.onStart();
    FirebaseRecyclerAdapter<Contact, ContactViewHolder > firebaseRecyclerAdapter =
            new FirebaseRecyclerAdapter<Contact, ContactViewHolder>(
                    Contact.class,
                    R.layout.contact_row,
                    ContactViewHolder.class,
                    mDatabase
            ) {
                @Override
                protected void populateViewHolder(ContactViewHolder viewHolder, Contact model, int position) {
                    viewHolder.setName(model.getName());
                    viewHolder.setAddress(model.getAddress());
                    viewHolder.setImage(getApplicationContext(), model.getImage());
                }
            };
    mContactList.setAdapter(firebaseRecyclerAdapter);
}

Creating a class ->OfflineCapability.Java

import android.app.Application;

import com.google.firebase.FirebaseApp;
import com.google.firebase.database.FirebaseDatabase;
import com.squareup.picasso.OkHttpDownloader;
import com.squareup.picasso.Picasso;

public class Offlinecapability extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        if(!FirebaseApp.getApps(this).isEmpty()) {
            FirebaseDatabase.getInstance().setPersistenceEnabled(true);
        }
        Picasso.Builder builder = new Picasso.Builder(this);
        builder.downloader(new OkHttpDownloader(this,Integer.MAX_VALUE));
        Picasso built = builder.build();
        built.setIndicatorsEnabled(false);
        Picasso.setSingletonInstance(built);
    }
}

As I said previously this is a very useful tool.For enabling this feature you have only write

FirebaseDatabase.getInstance().setPersistenceEnabled(true);
Picasso.Builder builder = new Picasso.Builder(this);
        builder.downloader(new OkHttpDownloader(this,Integer.MAX_VALUE));
        Picasso built = builder.build();
        built.setIndicatorsEnabled(false);
        Picasso.setSingletonInstance(built);

This is for Picasso image loader.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rubs.firebase">
<uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:name=".Offlinecapability"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".AddContact"></activity>
    </application>

</manifest>

You have to take permission for the Internet and don’t forget to declare your offlinecapability.java file here

android:name=".Offlinecapability"

Conclusion:-
In this Example, you saw how to use Firebase DataBase and Storage.I hope you will understand the method. In the case of any queries, you may ask questions. Keep following more amazing Android Blogs.


If you really liked the article, please subscribe to our YouTube Channel for videos related to this article.Please find us on Twitter and Facebook.

Leave a Reply

Your email address will not be published. Required fields are marked *