Android Firebase Email and Password Login as part of Android Firebase Device to Device Chat Application

In this tutorial, we are going to learn how to implement Android Firebase Email and Password Login. This is the first part of complete Android Firebase Chat application.

This part will only cover Android Firebase Email and Password Login and Registration and the ability to create a User Profile page after login.

In the course of this tutorial, we will explore how to use Android Firebase Real-time Database and Android Firebase Storage.

For this tutorial, we are going to create the following Activity pages.

1. Splash screen intro page

2. Firebase Email and Password login page

3. Firebase Sign-up / Registration page

4. User profile page using Navigation Drawer

5. User profile edit page using Firebase Database and Storage

In part 2 of this tutorial, we will implement android device to device communication using Upstream Firebase Cloud Messaging. We will go further to implement our server application using XMPP server which will communicate with Google Firebase Cloud Connection Server endpoint.

User will login or register in the application if they are using it for the first time. If login is successful, the user will be redirected to the user profile page. The user will be notify to update its profile page and also add a profile photo.

 

What we will be creating – Screenshot

These are some of the screenshots for this application we will be creating.

android chat

Setup Firebase Project

Follow the steps below to register and integrate Firebase SDK to your android project.

Go the Firebase webite and register if you don’t have an account already. The registration is very simple. After registration, go to the console dashboard and click on create new project button.

In the window modal, enter the name of your project and country as shown in the image below

Android firebase

Click on the create project button to continue. In the console, click the button add Firebase to your android app as shown below

Android firebase

In the next window, add the Package name of your application and click the Add App button as shown below.

Android firebase

Click the continue button to download a Json configuration file which will be added in the root App directory of your project. See the image below

Android firebase

Following the instructions on how to add the Google Services plugin and the Firebase SDK in build.gradle as shown below.

Android firebase

We have successfully added Firebase to our project. We will now focus on our android project.

Setup Firebase Database

Go to your Firebase Console and click on the database menu link

Click on the RULES menu tab and change the current rules to the code below

{}
{

"rules": {

".read": true,

".write": true

}

}

This is a public access to the database. Please be sure that you read the security and rules  sections of Firebase database. With the above rules, it means that anybody can get access to your database.

Make sure you click on the publish button after the changes. Also note that this rule is use for development and it is not advice to be used for production application.

firebase dashboard

 

Setup Firebase Login

We will enable the Firebase Email and Password Authentication in the Firebase Console as shown in the image below.

Firebase console Auth

 

Setup Firebase Storage

Also, we will edit the permission and make access to our Firebase Storage public. Please know that we are doing this because we are working a demo app but for production app, the best way is to grant access and restrict access to contents.

service firebase.storage {
match /b/fir-analyticexample.appspot.com/o {
match /{allPaths=**} {
allow read, write: if true;
}
}
}

CREATE ANDROID CLIENT APPLICATION

Lets start to soil our hands in code. Start up your IDE. For this tutorial, I am using the following tools and environment, feel free to use what works for you.

Windows 10

Android Studio

Sony Xperia ZL

Min SDK 14

Target SDK 23

To create a new android application project, follow the steps as stipulated below.

Go to File menu

Click on New menu

Click on Android Application

Enter Project name: AndroidFirebaseChat

Package: com.inducesmile.androidfirebasechat

Select Blank Activity

Name your activity : MainActivity

Keep other default selections

Continue to click on next button until Finish button is active, then click on Finish Button.

 

BUILD.GRADLE

We are going to complete Firebase integration in our android project by modifying the project build.gradle file.

Open the Project build.gradle file and add a classpath for google services as shown below.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0'
        classpath 'com.google.gms:google-services:3.0.0'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Open the app build.gradle, we are going to use some third party android library for network calls, dimensions, Firebase and much more. The updated version of the app level build.gradle is shown below

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion '25.0.0'

    defaultConfig {
        applicationId "com.inducesmile.androidfirebasechat"
        minSdkVersion 14
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.0.0'
    compile 'com.google.firebase:firebase-storage:9.2.0'
    compile 'com.google.firebase:firebase-auth:9.2.0'
    compile 'com.google.firebase:firebase-database:9.2.0'
    compile 'com.intuit.sdp:sdp-android:1.0.3'
    compile 'com.android.support:design:24.0.0'
    compile 'de.hdodenhof:circleimageview:1.2.1'
    compile 'com.android.support:support-v4:24.0.0'
    compile 'com.github.bumptech.glide:glide:3.7.0'
}
apply plugin: 'com.google.gms.google-services'

MANIFEST.XML

For now, we are going to add two changes in the Manifest.xml file. User permissions and a custom Application class. The two users permission we will use for the login part are INTERNET and READ_EXTERNAL_STORAGE.

Below is the updated version of the Manifest.xml file.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.inducesmile.androidfirebasechat">

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

    <application
        android:name=".FirebaseApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".LoginActivity" />
        <activity android:name=".SignUpActivity" />
        <activity
            android:name=".ProfileActivity"
            android:label="@string/title_activity_profile"
            android:theme="@style/AppTheme.NoActionBar" />
        <activity android:name=".EditProfileActivity">
        </activity>
    </application>

</manifest>

STRINGS.XML

We are going to update our project strings.xml file located in the values folder inside the res folder. Open the file and add the code below to it.

<resources>
    <string name="app_name">Android FireBase Chat</string>
    <string name="email_hint">Email</string>
    <string name="password_hint">Password</string>
    <string name="login_button">LOGIN</string>
    <string name="sign_up">Sign up</string>
    <string name="no_text"> </string>
    <string name="sign_up_button">SIGN UP</string>
    <string name="log_in">Login</string>
    <string name="title_activity_profile">ProfileActivity</string>
    <string name="navigation_drawer_open">Open navigation drawer</string>
    <string name="navigation_drawer_close">Close navigation drawer</string>
    <string name="action_settings">Settings</string>

    <string name="profile_name">Induce Smile</string>
    <string name="country_location">Sweden</string>

    <string name="menu_profile">Profile</string>
    <string name="menu_chat">Chat</string>
    <string name="menu_contact">Contact</string>
    <string name="menu_online">Online</string>

    <string name="menu_settings">Settings</string>
    <string name="menu_logout">Logout</string>

    <!-- TODO: Remove or change this placeholder text -->
    <string name="hello_blank_fragment">Hello blank fragment</string>

    <string name="profile_names">Display name</string>
    <string name="induce_smile">Induce Smile</string>

    <string name="edit_profile_name">Name</string>
    <string name="edit_profile_country">Country</string>
    <string name="edit_profile_phone">Phone number</string>
    <string name="edit_profile_hobby">Hobby</string>
    <string name="select_date">Date</string>
    <string name="save_edit">Save edit</string>

</resources>

COLORS.XML

Open the colors.xml file in the same location as the strings.xml file and add the code below to the file.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorWhite">#ffffff</color>
    <color name="colorBlack">#000000</color>
    <color name="colorMild">#9d9c9c</color>
    <color name="colorDivider">#eae6e6</color>
</resources>

Splash intro Screen

We will create a chat intro screen. It has only a RelativeLayout GroupView in its layout file as shown.

<?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:background="@drawable/chat_bg"
    tools:context="com.inducesmile.androidfirebasechat.MainActivity">

</RelativeLayout>

For the MainActivity class, a Handler class postDelayed() method is used with a runnable to delay the page transition for 5 second.

Feel free to change the delay in the final int variable – SPLASH_DISPLAY_LENGTH to anything time you want.

The code for the intro Activity class is as shown

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Handler;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends AppCompatActivity {

    private final int SPLASH_DISPLAY_LENGTH = 5000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null){
            actionBar.hide();
        }

        new Handler().postDelayed(new Runnable(){
            @Override
            public void run(){
                Intent startActivityIntent = new Intent(MainActivity.this, LoginActivity.class);
                startActivity(startActivityIntent);
                MainActivity.this.finish();
            }
        }, SPLASH_DISPLAY_LENGTH);
    }
}

Login with Email and Password Activity Page

In the package folder of your project, right click and create a new Activity file with its corresponding layout file. Name this file LoginActivity.

activity_login.xml

Open this layout file, we are going to add some View controls – EditText, Button and ImageView. Copy and add the below code the this file.

<?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:padding="@dimen/_16sdp"
    tools:context="com.inducesmile.androidfirebasechat.LoginActivity">

    <ImageView
        android:id="@+id/logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="@dimen/_32sdp"
        android:src="@drawable/logo"/>


    <TextView
        android:id="@+id/login_error"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/logo"
        android:textColor="@color/colorAccent"
        android:text="@string/no_text"
        android:padding="@dimen/_8sdp"
        android:layout_marginTop="@dimen/_56sdp"/>

    <EditText
        android:id="@+id/email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/email_hint"
        android:inputType="textEmailAddress"
        android:maxLines="1"
        android:padding="@dimen/_12sdp"
        android:background="@drawable/bottom_border"
        android:textColor="@color/colorBlack"
        android:layout_below="@+id/login_error"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/_8sdp"
        android:singleLine="true" />

    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/password_hint"
        android:inputType="textPassword"
        android:maxLines="1"
        android:padding="@dimen/_12sdp"
        android:textColor="@color/colorBlack"
        android:background="@drawable/bottom_border"
        android:layout_below="@+id/email"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/_8sdp"
        android:singleLine="true" />

    <Button
        android:id="@+id/login_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/password"
        android:layout_centerHorizontal="true"
        android:textColor="@color/colorWhite"
        android:text="@string/login_button"
        android:paddingBottom="@dimen/_16sdp"
        android:paddingTop="@dimen/_16sdp"
        android:textStyle="bold"
        android:background="@color/colorPrimaryDark"
        android:layout_marginTop="@dimen/_8sdp"/>

    <TextView
        android:id="@+id/register"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/_24sdp"
        android:textColor="@color/colorPrimaryDark"
        android:text="@string/sign_up"
        android:layout_below="@+id/login_button"
        android:layout_centerHorizontal="true"/>

</RelativeLayout>

LoginActivity.java

For the LoginActivity Class, we are going to get the instances of our View controls.

Since the Firebase Authencation management will be need in almost all the Activity class, we will create a custom Application class which will inherit from default android Application class.

Open the LoginActivity class and add the code below to the class

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.google.firebase.auth.FirebaseAuth;
import com.inducesmile.androidfirebasechat.Helper.Helper;

public class LoginActivity extends AppCompatActivity {

    private static final String TAG = LoginActivity.class.getSimpleName();

    private EditText emailInput;

    private EditText passwordInput;

    private TextView signUpText;

    private TextView loginError;

    private FirebaseAuth mAuth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null){
            actionBar.hide();
        }

        mAuth = ((FirebaseApplication)getApplication()).getFirebaseAuth();
        ((FirebaseApplication)getApplication()).checkUserLogin(LoginActivity.this);

        loginError = (TextView)findViewById(R.id.login_error);

        emailInput = (EditText)findViewById(R.id.email);
        passwordInput = (EditText)findViewById(R.id.password);

        signUpText = (TextView)findViewById(R.id.register);
        signUpText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent signUpIntent = new Intent(LoginActivity.this, SignUpActivity.class);
                startActivity(signUpIntent);
            }
        });

        final Button loginButton = (Button)findViewById(R.id.login_button);
        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String enteredEmail = emailInput.getText().toString();
                String enteredPassword = passwordInput.getText().toString();

                if(TextUtils.isEmpty(enteredEmail) || TextUtils.isEmpty(enteredPassword)){
                    Helper.displayMessageToast(LoginActivity.this, "Login fields must be filled");
                    return;
                }
                if(!Helper.isValidEmail(enteredEmail)){
                    Helper.displayMessageToast(LoginActivity.this, "Invalidate email entered");
                    return;
                }

                ((FirebaseApplication)getApplication()).loginAUser(LoginActivity.this, enteredEmail, enteredPassword, loginError);
            }
        });
    }

    @Override
    public void onStart() {
        super.onStart();
        //mAuth.addAuthStateListener(((FirebaseApplication)getApplication()).mAuthListener);
    }

    @Override
    public void onStop() {
        super.onStop();
        if (((FirebaseApplication)getApplication()).mAuthListener != null) {
            //mAuth.removeAuthStateListener(((FirebaseApplication)getApplication()).mAuthListener);
        }
    }
}

FirebaseApplication.java

This is how we created our project custom Application class which manages User Authentication.

Like before, new a new java file and name it FirebaseApplication.java.

Open the file and add the code below to the file.

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.TextView;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.inducesmile.androidfirebasechat.Helper.Helper;

public class FirebaseApplication extends Application {

    private static final String TAG = FirebaseApplication.class.getSimpleName();

    public FirebaseAuth firebaseAuth;

    public FirebaseAuth.AuthStateListener mAuthListener;

    public FirebaseAuth getFirebaseAuth(){
        return firebaseAuth = FirebaseAuth.getInstance();
    }

    public String getFirebaseUserAuthenticateId() {
        String userId = null;
        if(firebaseAuth.getCurrentUser() != null){
            userId = firebaseAuth.getCurrentUser().getUid();
        }
        return userId;
    }

    public void checkUserLogin(final Context context){
        if(firebaseAuth.getCurrentUser() != null){
            Intent profileIntent = new Intent(context, ProfileActivity.class);
            context.startActivity(profileIntent);
        }
    }

    public void isUserCurrentlyLogin(final Context context){
        mAuthListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                FirebaseUser user = firebaseAuth.getCurrentUser();
                if(null != user){
                    Intent profileIntent = new Intent(context, ProfileActivity.class);
                    context.startActivity(profileIntent);
                }else{
                    Intent loginIntent = new Intent(context, LoginActivity.class);
                    context.startActivity(loginIntent);
                }
            }
        };
    }

    public void createNewUser(Context context, String email, String password, final TextView errorMessage){
        firebaseAuth.createUserWithEmailAndPassword(email, password)
                .addOnCompleteListener((Activity) context, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful());
                if (!task.isSuccessful()) {
                    errorMessage.setText("Failed to login. Invalid user");
                }
            }
        });
    }

    public void loginAUser(final Context context, String email, String password, final TextView errorMessage){
        firebaseAuth.signInWithEmailAndPassword(email, password)
                .addOnCompleteListener((Activity)context, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (!task.isSuccessful()) {
                            Log.w(TAG, "signInWithEmail", task.getException());
                            errorMessage.setText("Failed to login");
                        }else {
                            Helper.displayMessageToast(context, "User has been login");
                            Intent profileIntent = new Intent(context, ProfileActivity.class);
                            context.startActivity(profileIntent);
                        }
                    }
                });
    }

}

Sign-up / Registration Activity Page

The registration page follows the same pattern with the login page except with few different method calls.

We will use only Email and Password for registration and once a user is registered, the user can then update its user information and much more.

The codes for the layout and activity class is as shown

activity_sign_up.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:padding="@dimen/_16sdp"
    tools:context="com.inducesmile.androidfirebasechat.SignUpActivity">

    <ImageView
        android:id="@+id/logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="@dimen/_32sdp"
        android:src="@drawable/logo"/>


    <TextView
        android:id="@+id/login_error"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/logo"
        android:textColor="@color/colorAccent"
        android:text="@string/no_text"
        android:padding="@dimen/_8sdp"
        android:layout_marginTop="@dimen/_56sdp"/>

    <EditText
        android:id="@+id/email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/email_hint"
        android:inputType="textEmailAddress"
        android:maxLines="1"
        android:padding="@dimen/_12sdp"
        android:background="@drawable/bottom_border"
        android:textColor="@color/colorBlack"
        android:layout_below="@+id/login_error"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/_8sdp"
        android:singleLine="true" />

    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/password_hint"
        android:inputType="textPassword"
        android:maxLines="1"
        android:padding="@dimen/_12sdp"
        android:textColor="@color/colorBlack"
        android:background="@drawable/bottom_border"
        android:layout_below="@+id/email"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="@dimen/_8sdp"
        android:singleLine="true" />

    <Button
        android:id="@+id/login_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/password"
        android:layout_centerHorizontal="true"
        android:textColor="@color/colorWhite"
        android:text="@string/sign_up_button"
        android:paddingBottom="@dimen/_16sdp"
        android:paddingTop="@dimen/_16sdp"
        android:textStyle="bold"
        android:background="@color/colorPrimaryDark"
        android:layout_marginTop="@dimen/_8sdp"/>

    <TextView
        android:id="@+id/register"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/_24sdp"
        android:textColor="@color/colorPrimaryDark"
        android:text="@string/log_in"
        android:layout_below="@+id/login_button"
        android:layout_centerHorizontal="true"/>

</RelativeLayout>

SignUpActivity.java

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.google.firebase.auth.FirebaseAuth;
import com.inducesmile.androidfirebasechat.Helper.Helper;

public class SignUpActivity extends AppCompatActivity {

    private static final String TAG = SignUpActivity.class.getSimpleName();

    private EditText emailInput;

    private EditText passwordInput;

    private TextView signUpText;

    private TextView loginError;

    private FirebaseAuth mAuth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sign_up);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null){
            actionBar.hide();
        }

        mAuth = ((FirebaseApplication)getApplication()).getFirebaseAuth();
        ((FirebaseApplication)getApplication()).checkUserLogin(SignUpActivity.this);

        loginError = (TextView)findViewById(R.id.login_error);

        emailInput = (EditText)findViewById(R.id.email);
        passwordInput = (EditText)findViewById(R.id.password);

        signUpText = (TextView)findViewById(R.id.register);
        signUpText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent signUpIntent = new Intent(SignUpActivity.this, LoginActivity.class);
                startActivity(signUpIntent);
            }
        });

        final Button loginButton = (Button)findViewById(R.id.login_button);
        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String enteredEmail = emailInput.getText().toString();
                String enteredPassword = passwordInput.getText().toString();

                if(TextUtils.isEmpty(enteredEmail) || TextUtils.isEmpty(enteredPassword)){
                    Helper.displayMessageToast(SignUpActivity.this, "Login fields must be filled");
                    return;
                }
                if(!Helper.isValidEmail(enteredEmail)){
                    Helper.displayMessageToast(SignUpActivity.this, "Invalidate email entered");
                    return;
                }

                ((FirebaseApplication)getApplication()).createNewUser(SignUpActivity.this, enteredEmail, enteredPassword, loginError);
            }
        });
    }
}

UserProfile Page

The user profile page will be a little complicated since according to the design, we will create android Navigation Drawer template which will serve as a menu navigation and also user profile.

Create a new Android Activity class using the Navigation Drawer Template. Name the file ProfileActivity.java.

We will make the following modification to the file as shown below.

import android.os.Bundle;
import android.support.design.internal.NavigationMenuView;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

public class ProfileActivity extends AppCompatActivity{

    private FragmentManager fragmentManager;

    private Fragment fragment = null;

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

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        fragmentManager = getSupportFragmentManager();
        final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragment = new ProfileFragment();
        fragmentTransaction.replace(R.id.main_container_wrapper, fragment);
        fragmentTransaction.commit();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        disableNavigationViewScrollbars(navigationView);
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem item) {
                int id = item.getItemId();

                if (id == R.id.nav_profile) {
                    fragment = new ProfileFragment();
                } else if (id == R.id.nav_chat) {

                } else if (id == R.id.nav_contact) {

                } else if (id == R.id.nav_online) {

                } else if (id == R.id.nav_settings) {

                } else if (id == R.id.nav_logout) {

                }

                FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.main_container_wrapper, fragment);
                transaction.commit();

                DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
                assert drawer != null;
                drawer.closeDrawer(GravityCompat.START);
                return true;
            }
        });
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //getMenuInflater().inflate(R.menu.profile, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void disableNavigationViewScrollbars(NavigationView navigationView) {
        if (navigationView != null) {
            NavigationMenuView navigationMenuView = (NavigationMenuView) navigationView.getChildAt(0);
            if (navigationMenuView != null) {
                navigationMenuView.setVerticalScrollBarEnabled(false);
            }
        }
    }
}

Layout files

For the layout files that accompanying it, we will also do a little changes to fit our project requirement.

Activity_profile.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_profile"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        android:scrollbars="none"
        app:headerLayout="@layout/nav_header_profile"
        app:menu="@menu/activity_profile_drawer" />

</android.support.v4.widget.DrawerLayout>

app_bar_profile.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"
    android:fitsSystemWindows="true"
    tools:context="com.inducesmile.androidfirebasechat.ProfileActivity">

    <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_profile" />

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

content_profile.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_container_wrapper"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.inducesmile.androidfirebasechat.ProfileActivity"
    tools:showIn="@layout/app_bar_profile">

</RelativeLayout>

nav_header_profile.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="@dimen/nav_header_height"
    android:background="@color/colorPrimary"
    android:gravity="bottom"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="@dimen/_8sdp"
        android:src="@drawable/small_profile_image"
        android:id="@+id/circleView"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="@dimen/_18sdp"
        android:textSize="@dimen/_16sdp"
        android:text="@string/profile_name"
        android:layout_gravity="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="@dimen/_12sdp"
        android:layout_gravity="center"
        android:layout_marginTop="@dimen/_8sdp"
        android:text="@string/country_location" />

</LinearLayout>

Fragment Menu Options

For each of the menu options in the Navigation drawer, we will represent the content with a Fragment class. The Fragment class will be add to the host activity layout once its menu link is click.

First we will create the ProfileFragment class with its corresponding layout file. In the next tutorial, we will create other Fragment classes that represent the remaining menus.

ProfileFragment.java

The ProfileFragment will contain the user profile information and photo. The detail information will be bind to a RecyclerView control. We will also add a menu icon that will be use to update the user profile information.

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.inducesmile.androidfirebasechat.Firebase.FirebaseDatabaseHelper;
import com.inducesmile.androidfirebasechat.Firebase.FirebaseStorageHelper;
import com.inducesmile.androidfirebasechat.Helper.Helper;
import com.inducesmile.androidfirebasechat.Helper.SimpleDividerItemDecoration;

public class ProfileFragment extends Fragment {

    private static final String TAG = ProfileFragment.class.getSimpleName();

    private ImageView profilePhoto;

    private TextView profileName;

    private TextView country;

    private TextView userStatus;

    private RecyclerView recyclerView;

    private LinearLayoutManager linearLayoutManager;

    private String id;

    private static final int REQUEST_READ_PERMISSION = 120;

    public ProfileFragment() {
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_profile, container, false);

        getActivity().setTitle("My Profile");

        profileName = (TextView)view.findViewById(R.id.profile_name);
        country = (TextView)view.findViewById(R.id.country);
        profileName.setVisibility(View.GONE);
        country.setVisibility(View.GONE);

        profilePhoto = (ImageView)view.findViewById(R.id.circleView);
        profilePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                final Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
                galleryIntent.setType("image/*");
                startActivityForResult(galleryIntent, Helper.SELECT_PICTURE);
            }
        });

        recyclerView = (RecyclerView)view.findViewById(R.id.profile_list);
        linearLayoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.addItemDecoration(new SimpleDividerItemDecoration(getActivity()));

        ((FirebaseApplication)getActivity().getApplication()).getFirebaseAuth();
        id = ((FirebaseApplication)getActivity().getApplication()).getFirebaseUserAuthenticateId();

        FirebaseDatabaseHelper firebaseDatabaseHelper = new FirebaseDatabaseHelper();
        firebaseDatabaseHelper.isUserKeyExist(id, getActivity(), recyclerView);
        return view;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.edit_profile, menu);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if(id == R.id.action_edit_profile){
            Intent editProfileIntent = new Intent(getActivity(), EditProfileActivity.class);
            getActivity().startActivity(editProfileIntent);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        System.out.println("user id has entered onActivityResult ");
        if (requestCode == Helper.SELECT_PICTURE) {
            Uri selectedImageUri = data.getData();
            String imagePath = getPath(selectedImageUri);
            FirebaseStorageHelper storageHelper = new FirebaseStorageHelper(getActivity());

            if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_READ_PERMISSION);
                return;
            }
            storageHelper.saveProfileImageToCloud(id, selectedImageUri, profilePhoto);
        }
    }

    public String getPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
        assert cursor != null;
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        int columnIndex = cursor.getColumnIndex(projection[0]);
        String filePath = cursor.getString(columnIndex);
        cursor.close();
        return filePath;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == REQUEST_READ_PERMISSION) {
            if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                Toast.makeText(getActivity(), "Sorry!!!, you can't use this app without granting this permission", Toast.LENGTH_LONG).show();
            }
        }
    }
}

 fragment_profile.xml

The layout file for this class is as shown below

<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"
    tools:context="com.inducesmile.androidfirebasechat.ProfileFragment">

    <LinearLayout
        android:id="@+id/profile_header"
        android:layout_width="match_parent"
        android:layout_height="@dimen/_130sdp"
        android:orientation="vertical"
        android:gravity="center"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:background="@color/colorPrimary">

        <de.hdodenhof.circleimageview.CircleImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:src="@drawable/small_profile_image"
            android:id="@+id/circleView"/>

        <TextView
            android:id="@+id/profile_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="@dimen/_18sdp"
            android:textSize="@dimen/_16sdp"
            android:text="@string/profile_name"
            android:textColor="@color/colorWhite"
            android:layout_gravity="center"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

        <TextView
            android:id="@+id/country"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="@dimen/_12sdp"
            android:textColor="@color/colorWhite"
            android:layout_gravity="center"
            android:layout_marginTop="@dimen/_8sdp"
            android:text="@string/country_location" />

    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/profile_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/profile_header"
        android:layout_centerHorizontal="true"
        android:orientation="vertical"
        android:scrollbars="none"/>


</RelativeLayout>

RecyclerViewAdapter

Create a new package and name it Adapters. We will add the RecyclerViewAdapter for the user profile information.

RecyclerViewAdapter.java

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.inducesmile.androidfirebasechat.R;
import com.inducesmile.androidfirebasechat.UserProfile;

import java.util.List;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> {

    private List<UserProfile> user;

    protected Context context;

    public RecyclerViewAdapter(Context context, List<UserProfile> user) {
        this.user = user;
        this.context = context;
    }

    @Override
    public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
        RecyclerViewHolders viewHolder = null;
        View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.profile_data_list, parent, false);
        viewHolder = new RecyclerViewHolders(layoutView);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerViewHolders holder, int position) {
        holder.profileHeader.setText(user.get(position).getHeader());
        holder.profileContent.setText(user.get(position).getProfileContent());
    }

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

}

RecyclerViewHolders.java

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

import com.inducesmile.androidfirebasechat.R;

public class RecyclerViewHolders extends RecyclerView.ViewHolder{

    private static final String TAG = RecyclerViewHolders.class.getSimpleName();

    public TextView profileHeader;

    public TextView profileContent;

    public RecyclerViewHolders(final View itemView) {
        super(itemView);
        profileHeader = (TextView)itemView.findViewById(R.id.heading);
        profileContent = (TextView) itemView.findViewById(R.id.profile_content);
    }
}

Add the layout file that the adapter class uses to bind its data to the RecyclerView instance.

profile_data_list.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="wrap_content"
    android:padding="@dimen/_8sdp"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/heading"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="@dimen/_8sdp"
        android:text="@string/profile_names"
        android:textColor="@color/colorMild"
        android:layout_weight="4"/>

    <TextView
        android:id="@+id/profile_content"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="@dimen/_8sdp"
        android:text="@string/induce_smile"
        android:textColor="@color/colorMild"
        android:layout_weight="6"/>

</LinearLayout>

EditProfileActivity.java

This class contains all the field that represents user profile properties. The code source code is as shown below.

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.inducesmile.androidfirebasechat.Firebase.FirebaseDatabaseHelper;
import com.inducesmile.androidfirebasechat.Firebase.FirebaseUserEntity;
import com.inducesmile.androidfirebasechat.Helper.Helper;

public class EditProfileActivity extends AppCompatActivity {

    private static final String TAG = EditProfileActivity.class.getSimpleName();

    private EditText editProfileName;

    private EditText editProfileCountry;

    private EditText editProfilePhoneNumber;

    private EditText editProfileHobby;

    private EditText editProfileBirthday;

    private FirebaseAuth.AuthStateListener authStateListener;

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

        setTitle("Edit Profile Information");

        editProfileName = (EditText)findViewById(R.id.profile_name);
        editProfileCountry = (EditText)findViewById(R.id.profile_country);
        editProfilePhoneNumber = (EditText)findViewById(R.id.profile_phone);
        editProfileHobby = (EditText)findViewById(R.id.profile_hobby);
        editProfileBirthday = (EditText)findViewById(R.id.profile_birth);

        Button saveEditButton = (Button)findViewById(R.id.save_edit_button);
        saveEditButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String profileName = editProfileName.getText().toString();
                String profileCountry = editProfileCountry.getText().toString();
                String profilePhoneNumber = editProfilePhoneNumber.getText().toString();
                String profileHobby = editProfileHobby.getText().toString();
                String profileBirthday = editProfileBirthday.getText().toString();

                // update the user profile information in Firebase database.
                if(TextUtils.isEmpty(profileName) || TextUtils.isEmpty(profileCountry) || TextUtils.isEmpty(profilePhoneNumber)
                        || TextUtils.isEmpty(profileHobby) || TextUtils.isEmpty(profileBirthday)){
                    Helper.displayMessageToast(EditProfileActivity.this, "All fields must be filled");
                }

                FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
                if (user == null) {
                    Intent firebaseUserIntent = new Intent(EditProfileActivity.this, LoginActivity.class);
                    startActivity(firebaseUserIntent);
                    finish();
                } else {
                    String userId = user.getProviderId();
                    String id = user.getUid();
                    String profileEmail = user.getEmail();

                    FirebaseUserEntity userEntity = new FirebaseUserEntity(id, profileEmail, profileName, profileCountry, profilePhoneNumber, profileBirthday, profileHobby);
                    FirebaseDatabaseHelper firebaseDatabaseHelper = new FirebaseDatabaseHelper();
                    firebaseDatabaseHelper.createUserInFirebaseDatabase(id, userEntity);

                    editProfileName.setText("");
                    editProfileCountry.setText("");
                    editProfilePhoneNumber.setText("");
                    editProfileHobby.setText("");
                    editProfileBirthday.setText("");
                }
            }
        });
    }
}

activity_edit_profile.xml

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/_16sdp"
    android:orientation="vertical"
    tools:context="com.inducesmile.androidfirebasechat.EditProfileActivity">

    <EditText
        android:id="@+id/profile_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/edit_profile_name"
        android:inputType="textPersonName"
        android:maxLines="1"
        android:padding="@dimen/_12sdp"
        android:textSize="@dimen/_12sdp"
        android:background="@drawable/bottom_border"
        android:textColor="@color/colorBlack"
        android:singleLine="true" />

    <EditText
        android:id="@+id/profile_country"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/edit_profile_country"
        android:inputType="text"
        android:maxLines="1"
        android:padding="@dimen/_12sdp"
        android:textSize="@dimen/_12sdp"
        android:background="@drawable/bottom_border"
        android:textColor="@color/colorBlack"
        android:layout_marginTop="@dimen/_16sdp"
        android:singleLine="true" />

    <EditText
        android:id="@+id/profile_phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/edit_profile_phone"
        android:inputType="phone"
        android:maxLines="1"
        android:padding="@dimen/_12sdp"
        android:textSize="@dimen/_12sdp"
        android:background="@drawable/bottom_border"
        android:textColor="@color/colorBlack"
        android:layout_marginTop="@dimen/_8sdp"
        android:singleLine="true" />

    <EditText
        android:id="@+id/profile_hobby"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/edit_profile_hobby"
        android:inputType="text"
        android:maxLines="1"
        android:padding="@dimen/_12sdp"
        android:textSize="@dimen/_12sdp"
        android:background="@drawable/bottom_border"
        android:textColor="@color/colorBlack"
        android:layout_marginTop="@dimen/_8sdp"
        android:singleLine="true" />

    <LinearLayout
        android:id="@+id/select_date"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/_8sdp"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/profile_birth"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="7"
            android:inputType="text"
            android:maxLines="1"
            android:padding="@dimen/_12sdp"
            android:textSize="@dimen/_12sdp"
            android:background="@drawable/bottom_border"
            android:textColor="@color/colorBlack"
            android:layout_marginTop="@dimen/_8sdp"
            android:singleLine="true" />

        <Button
            android:id="@+id/profile_birth_button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/_8sdp"
            android:textColor="@color/colorWhite"
            android:text="@string/select_date"
            android:background="@color/colorPrimaryDark"
            android:layout_weight="3"/>

    </LinearLayout>

    <Button
        android:id="@+id/save_edit_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/_8sdp"
        android:textColor="@color/colorWhite"
        android:text="@string/save_edit"
        android:background="@color/colorPrimaryDark"
        android:padding="@dimen/_12sdp"/>

</LinearLayout>

Firebase Package

Create a new package in your project and call it Firebase. This folder will contain our interface class that communicate with Firebase Real-time Database and Storage.

Create the follow files with the code snippets in this folder.

FirebaseDatabaseHelper.java

import android.app.Activity;
import android.content.Context;
import android.support.v7.widget.RecyclerView;

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.inducesmile.androidfirebasechat.Adapters.RecyclerViewAdapter;
import com.inducesmile.androidfirebasechat.Helper.Helper;
import com.inducesmile.androidfirebasechat.UserProfile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FirebaseDatabaseHelper {

    private static final String TAG = FirebaseDatabaseHelper.class.getSimpleName();

    private DatabaseReference databaseReference;

    public FirebaseDatabaseHelper(){
        databaseReference = FirebaseDatabase.getInstance().getReference();
    }

    public void createUserInFirebaseDatabase(String userId, FirebaseUserEntity firebaseUserEntity){
        Map<String, FirebaseUserEntity> user = new HashMap<String, FirebaseUserEntity>();
        user.put(userId, firebaseUserEntity);
        databaseReference.child("users").setValue(user);
    }

    public void isUserKeyExist(final String uid, final Context context, final RecyclerView recyclerView){
        databaseReference.child("users").addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                System.out.println("User login 1 " + dataSnapshot.getKey() + " " + dataSnapshot.getValue());
                List<UserProfile> userData = adapterSourceData(dataSnapshot, uid);
                System.out.println("User login Size " + userData.size());
                RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter((Activity)context, userData);
                recyclerView.setAdapter(recyclerViewAdapter);
            }

            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
                List<UserProfile> userData = adapterSourceData(dataSnapshot, uid);
                System.out.println("User login Size " + userData.size());
                RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter((Activity)context, userData);
                recyclerView.setAdapter(recyclerViewAdapter);
            }

            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {

            }

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

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

    private List<UserProfile> adapterSourceData(DataSnapshot dataSnapshot, String uId){
        List<UserProfile> allUserData = new ArrayList<UserProfile>();
        if(dataSnapshot.getKey().equals(uId)){
            FirebaseUserEntity userInformation = dataSnapshot.getValue(FirebaseUserEntity.class);
            allUserData.add(new UserProfile(Helper.NAME, userInformation.getName()));
            allUserData.add(new UserProfile(Helper.EMAIL, userInformation.getEmail()));
            allUserData.add(new UserProfile(Helper.BIRTHDAY, userInformation.getBirthday()));
            allUserData.add(new UserProfile(Helper.PHONE_NUMBER, userInformation.getPhone()));
            allUserData.add(new UserProfile(Helper.HOBBY_INTEREST, userInformation.getHobby()));
        }
        return allUserData;
    }
}

FirebaseStorageHelper.java

import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;

public class FirebaseStorageHelper {

    private static final String TAG = FirebaseStorageHelper.class.getCanonicalName();

    private FirebaseStorage firebaseStorage;

    private StorageReference rootRef;

    private Context context;

    public FirebaseStorageHelper(Context context){
        this.context = context;
        init();
    }

    private void init(){
        this.firebaseStorage = FirebaseStorage.getInstance();
        rootRef = firebaseStorage.getReferenceFromUrl("add your Firebase database path");
    }

    public void saveProfileImageToCloud(String userId, Uri selectedImageUri, final ImageView imageView) {

        StorageReference photoParentRef = rootRef.child(userId);
        StorageReference photoRef = photoParentRef.child(selectedImageUri.getLastPathSegment());
        UploadTask uploadTask = photoRef.putFile(selectedImageUri);

        uploadTask.addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.d(TAG, "OnFailure " + e.getMessage());
            }
        }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                Uri downloadUrl = taskSnapshot.getDownloadUrl();
                Glide.with(context).load(downloadUrl.getPath()).into(imageView);
            }
        });

    }
}

FirebaseUserEntity.java

public class FirebaseUserEntity {

    private String uId;

    private String email;

    private String name;

    private String country;

    private String phone;

    private String birthday;

    private String hobby;

    public FirebaseUserEntity(){
    }

    public FirebaseUserEntity(String uId, String email, String name, String country, String phone, String birthday, String hobby) {
        this.uId = uId;
        this.email = email;
        this.name = name;
        this.country = country;
        this.phone = phone;
        this.birthday = birthday;
        this.hobby = hobby;
    }

    public String getuId() {
        return uId;
    }

    public String getEmail() {
        return email;
    }

    public String getName() {
        return name;
    }

    public String getCountry() {
        return country;
    }

    public String getPhone() {
        return phone;
    }

    public String getBirthday() {
        return birthday;
    }

    public String getHobby() {
        return hobby;
    }
}

Helper.java

import android.content.Context;
import android.widget.Toast;

public class Helper {

    public static final String NAME = "Name";

    public static final String EMAIL = "Email";

    public static final String BIRTHDAY = "Birthday";

    public static final String PHONE_NUMBER = "Phone Number";

    public static final String HOBBY_INTEREST = "Hobby & Interest";

    public static final int SELECT_PICTURE = 2000;

    public static boolean isValidEmail(String email){
        if(email.contains("@")){
            return true;
        }
        return false;
    }

    public static void displayMessageToast(Context context, String displayMessage){
        Toast.makeText(context, displayMessage, Toast.LENGTH_LONG).show();
    }
}

This brings us to the end of this tutorial. I hope that you have learn something. Run your app and see for yourself.

You can download the code for this tutorial below. If you are having hard time downloading the tutorial, kindly contact me.

Remember to subscribe with your email address so that you will be among the first to receive my new android blog post once it is published.

Please if you love this tutorial, kindly download my android app – Complete Mathematics – in Google Play Store and let me know what you think about it.

35 Comments

    • Inducesmile
    • Inducesmile
    • Inducesmile
    • Inducesmile
    • Inducesmile

Add a Comment