Wednesday , January 12 2022

Firebase MVVM Example – Implementing Authentication – Android Coding by DMTechnolab

Recently we finished learning MVVM Design Pattern In Android app development, and learning that we have used the Rastful API to communicate with our back end. But sometimes we build server less applications using Firebase. And some people asked “How do I follow MVVM when using Firebase?“. This is why in this Firebase MVVM example we will learn to implement it Firebase Authentication with MVVM Design Pattern.

Prerequisites

If you are an absolute newbie and came here by mistake, I would like to tell you that this post is not for you. You should know these things before proceeding in this post.

  1. What is MVVM Design Pattern?
  2. How to implement firebase authentication

If you do not know these things, then take your time and go through the above courses first. Then you can follow this. And if you are brave enough to follow it without the above mentioned courses, it’s terrible let’s start. And I forgot one thing, we also need a little bit RxJava and RxAndroid.

Creating Android Project

As always we need to create a new Android Studio project. Here, I am creating a project called “Firebase Authentic MVVM”. You can change the name if you want. But make sure that you have the following settings when creating the project.

Firebase mvvm example
Firebase mvvm example

Once your project is loaded, we will start adding the required dependencies.

Add required dependencies

First add the following to your app level build.gradle file. You need to add all these lines inside Dependency Section Maitha.

// ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"

    //New Material Design
    implementation 'com.google.android.material:material:1.1.0-alpha07'

    //Kodein Dependency Injection
    implementation "org.kodein.di:kodein-di-generic-jvm:6.2.1"
    implementation "org.kodein.di:kodein-di-framework-android-x:6.2.1"

    //RxJava
    implementation "io.reactivex.rxjava2:rxjava:2.2.5"
    implementation "io.reactivex.rxjava2:rxandroid:2.1.0"

As you can see we are going to use ViewModel, LiveData, Material Design, Codeine Dependency Injection and RxJava. But apart from all these dependencies, the most important thing we need is Firebase. And we haven’t added it yet. But don’t worry, project sync for now.

Add firebase authentication

Now it is very easy to add Firebase and I have already discussed it many times in videos and posts. So I think it makes no sense to explain the same thing over and over again. You can go Tools -> Firebase To add Firebase authentication in Android Studio. If you still have confusion then you can check This link where i added firebase cloud messaging. But you do not need to add cloud messaging, you need to add authentication. So select authentication instead of cloud messaging and the process is the same.

Enable data binding

As we are going to implement View Model ViewModel Design patterns and data bindings are an important point of this pattern. So let’s enable data binding.

  • Go to the app level build.gradle file again and enable data binding by adding the following code inside the Android block.
dataBinding {
        enabled = true
    }

  • After that inside the file gradle.properties Add this line to the bottom.
android.databinding.enableV2=true

  • Now finally sync your project and we’re good to go.

Package making

When you need to open different files of your project, it is very important to properly organize the codes into different packages. Haha 4 . So first we will create the following package structure in our Android Studio. Just to keep things well organized.

Firebase mvvm example
Firebase mvvm example

As you can see I have designed the main packages

  1. Data: Inside this package we will store the model and the repository. So again we have two more packages inside this package.
  2. Oi: Everything related to the UI will go within this package (Activities, Fragments, Viewmodels, Adapters etc.). Inside this package we have two more packages for Authentic and our application’s home screen.
  3. Pot: Inside this package we will store helper functions.

Now finally your refactor Main activity As Loginactivity And activity_main.xml As activity_login.xml. Because MainActivity is our LoginActivity and a sensible name change is always a good idea. So reflect both XML and Kotlin for activity and we are good to go.

Creating activities

In this project we basically need three activities. For login, for signup and for home. We already have login and we need to create Home and Signup activity. So create empty activities in Authentic and Home Package as shown in the image below.

Firebase mvvm example
Firebase mvvm example

So when the user is authenticated by logins or signup activity, we will display homeactivity.

As per the MVVM design rule, our view can communicate with the ViewModel, the ViewModel can communicate with the repository, and the repository can communicate with our back end, which in this case is Firebase.

So first we will create a firebase class to handle firebase operations.

Creating firebase source

  • Create another named package inside your data package Fire. And inside this package is a class named FirebaseSource.
class FirebaseSource {

    private val firebaseAuth: FirebaseAuth by lazy {
        FirebaseAuth.getInstance()
    }


    fun login(email: String, password: String) = Completable.create { emitter ->
        firebaseAuth.signInWithEmailAndPassword(email, password).addOnCompleteListener {
            if (!emitter.isDisposed) {
                if (it.isSuccessful)
                    emitter.onComplete()
                else
                    emitter.onError(it.exception!!)
            }
        }
    }

    fun register(email: String, password: String) = Completable.create { emitter ->
        firebaseAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener {
            if (!emitter.isDisposed) {
                if (it.isSuccessful)
                    emitter.onComplete()
                else
                    emitter.onError(it.exception!!)
            }
        }
    }

    fun logout() = firebaseAuth.signOut()

    fun currentUser() = firebaseAuth.currentUser

}

  • As you can see in the above class we have 3 functions, to login, signup, logout and currently log in user. The code is a lot more self-explanatory, and is almost the same as we do with Firebase. The only difference here, we are using Complete This is an RxJava class. Compleatable basically means that it is something that will be completed and we can get a signal when it will complete or fail. And it is the perfect class to use with FirebaseAuth because privilege is a network operation that will complete and we need to know if it has completed or failed.
  • So here we are creating a completeness and inside completeness we are authenticating. Once this is completed, we are using the emitter to indicate whether the task has been completed or failed. Very easy, I think.

So we have FirebaseSource, and now we need a repository so that we can communicate with Firebase.

Create User Repository

  • Inside the repository package (which is inside the data) create a new class named UserRepository. To build this class we will pass the firebase we just created. And then with the help of Firebase source, we will do the necessary operations.
class UserRepository (
    private val firebase: FirebaseSource
){
    fun login(email: String, password: String) = firebase.login(email, password)

    fun register(email: String, password: String) = firebase.register(email, password)

    fun currentUser() = firebase.currentUser()

    fun logout() = firebase.logout()
}

  • As you can see the code is very simple. We are just calling the function, which we have defined in. FirebaseSource.
  • We now have a repository that will communicate with our backend. And we need a ViewModel that can communicate with the repository.

But we also need a certifier here so that when the task is finished, we can fire the callback inside our activity to determine what happened to the login or signup operation.

A certifier

  • Create an interface named (which is inside the ui) inside the orthical package Certifier.
interface AuthListener {
    fun onStarted()
    fun onSuccess()
    fun onFailure(message: String)
}

  • Now we will build our Visual model.

Creating AuthViewModel and Factory

AuthViewModel

  • Inside again Justification Creates a new class named Package AuthViewModel.
class AuthViewModel(
    private val repository: UserRepository
) : ViewModel() {

    //email and password for the input
    var email: String? = null
    var password: String? = null

    //auth listener
    var authListener: AuthListener? = null


    //disposable to dispose the Completable
    private val disposables = CompositeDisposable()

    val user by lazy {
        repository.currentUser()
    }

    //function to perform login
    fun login() {

        //validating email and password
        if (email.isNullOrEmpty() || password.isNullOrEmpty()) {
            authListener?.onFailure("Invalid email or password")
            return
        }

        //authentication started
        authListener?.onStarted()

        //calling login from repository to perform the actual authentication
        val disposable = repository.login(email!!, password!!)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                //sending a success callback
                authListener?.onSuccess()
            }, {
                //sending a failure callback
                authListener?.onFailure(it.message!!)
            })
        disposables.add(disposable)
    }

    //Doing same thing with signup
    fun signup() {
        if (email.isNullOrEmpty() || password.isNullOrEmpty()) {
            authListener?.onFailure("Please input all values")
            return
        }
        authListener?.onStarted()
        val disposable = repository.register(email!!, password!!)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                authListener?.onSuccess()
            }, {
                authListener?.onFailure(it.message!!)
            })
        disposables.add(disposable)
    }

    fun goToSignup(view: View) {
        Intent(view.context, SignupActivity::class.java).also {
            view.context.startActivity(it)
        }
    }

    fun goToLogin(view: View) {
        Intent(view.context, LoginActivity::class.java).also {
            view.context.startActivity(it)
        }
    }


    //disposing the disposables
    override fun onCleared() {
        super.onCleared()
        disposables.dispose()
    }

}

  • And we have ViewModel, now we just need to use DataBinding with our activity.

AuthViewModel Factory

  • As we need the UserRepository inside the AuthViewModel, we need to create a ViewModel with the required parameters to the ViewModel.
  • So create another class by name Authentic visual Inside the ortical package.
@Suppress("UNCHECKED_CAST")
class AuthViewModelFactory(
    private val repository: UserRepository
) : ViewModelProvider.NewInstanceFactory() {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return AuthViewModel(repository) as T
    }

}

Designing UI and Binding Data

Login activity

  • Go inside yourself activity_login.xml And paste the following code.
<?xml version="1.0" encoding="utf-8"?>
<layout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
>

    <data>
        <variable name="viewmodel"
                  type="net.simplifiedcoding.ui.auth.AuthViewModel"/>
    </data>

    <RelativeLayout android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="#008577"
                    android:orientation="vertical"
                    tools:context=".ui.auth.LoginActivity"
                    android:scrollbarAlwaysDrawVerticalTrack="true">

        <RelativeLayout
                android:id="@+id/loginLayout"
                android:layout_centerInParent="true"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

            <TextView
                    android:id="@+id/login_title"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="16dp"
                    android:gravity="center_horizontal"
                    android:text="Account Login"
                    android:textColor="#fff"
                    android:textSize="26sp"
                    android:textStyle="bold"/>

            <RelativeLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/login_title"
                    android:layout_marginLeft="30dp"
                    android:layout_marginRight="30dp"
                    android:layout_marginTop="70dp"
                    android:background="#fff"
                    android:elevation="4dp"
                    android:orientation="vertical"
                    android:padding="20dp">

                <LinearLayout
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:orientation="vertical"
                        android:paddingTop="30dp">


                    <TextView
                            android:labelFor="@id/text_email"
                            android:text="email"
                            android:fontFamily="sans-serif-light"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"/>

                    <EditText
                            android:id="@+id/text_email"
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:drawableLeft="@drawable/ic_email"
                            android:drawablePadding="10dp"
                            android:singleLine="true"
                            android:text="@={viewmodel.email}"
                            android:layout_marginBottom="10dp"
                            android:hint="john@gmail.com"
                            android:inputType="textEmailAddress"/>

                    <TextView
                            android:labelFor="@id/edit_text_password"
                            android:text="password"
                            android:fontFamily="sans-serif-light"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"/>

                    <EditText
                            android:drawablePadding="10dp"
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:singleLine="true"
                            android:text="@={viewmodel.password}"
                            android:id="@+id/edit_text_password"
                            android:drawableLeft="@drawable/ic_lock"
                            android:hint="Password"
                            android:inputType="textPassword"/>


                    <TextView
                            android:id="@+id/text_view_forget_password"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="right"
                            android:paddingTop="5dp"
                            android:text="Forgot Password?"/>


                    <Button
                            android:id="@+id/button_sign_in"
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:layout_margin="22dp"
                            android:onClick="@{() -> viewmodel.login()}"
                            android:background="#d67601"
                            android:text="Log in"
                            android:textAllCaps="false"
                            android:textColor="#fff"
                            android:textSize="18sp"/>

                    <TextView
                            android:id="@+id/text_view_register"
                            android:layout_gravity="center_horizontal"
                            android:textAppearance="@style/TextAppearance.AppCompat.Headline"
                            android:textAlignment="center"
                            android:onClick="@{(v) -> viewmodel.goToSignup(v)}"
                            android:text="Don't have an account.nRegister Here"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"/>
                </LinearLayout>

            </RelativeLayout>

            <ImageButton
                    android:id="@+id/user_profile_photo"
                    android:layout_width="100dp"
                    android:layout_height="100dp"
                    android:layout_below="@+id/login_title"
                    android:layout_centerHorizontal="true"
                    android:layout_marginTop="16dp"
                    android:background="@drawable/user_profile_image_background"
                    android:elevation="4dp"
                    android:src="@drawable/ic_boy"/>

        </RelativeLayout>

        <ProgressBar
                android:id="@+id/progressbar"
                android:visibility="gone"
                android:layout_centerInParent="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

    </RelativeLayout>

</layout>

  • The above XML code will generate the following layout.
Firebase authentication mvvm
Firebase authentication mvvm

But I have used some drawable resources to design the above layout. And after copying and pasting you will see some error that those resources are missing. But don’t worry you can get my source code and all the resources at the end of this post.

Also make sure inside the data tag, you have given your ViewModel path according to your project.

Signup activity

Now we will do the same thing in SignupActivity.

  • First copy the following XML in. activity_signup.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
>

    <data>
        <variable name="viewmodel"
                  type="net.simplifiedcoding.ui.auth.AuthViewModel"/>
    </data>

    <RelativeLayout android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="#008577"
                    android:orientation="vertical"
                    tools:context=".ui.auth.SignupActivity"
                    android:scrollbarAlwaysDrawVerticalTrack="true">

        <RelativeLayout
                android:id="@+id/signupLayout"
                android:layout_centerInParent="true"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

            <TextView
                    android:id="@+id/login_title"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="16dp"
                    android:gravity="center_horizontal"
                    android:text="New User Signup"
                    android:textColor="#fff"
                    android:textSize="26sp"
                    android:textStyle="bold"/>

            <RelativeLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/login_title"
                    android:layout_marginLeft="30dp"
                    android:layout_marginRight="30dp"
                    android:layout_marginTop="70dp"
                    android:background="#fff"
                    android:elevation="4dp"
                    android:orientation="vertical"
                    android:padding="20dp">

                <LinearLayout
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:orientation="vertical"
                        android:paddingTop="30dp">


                    <TextView
                            android:labelFor="@id/text_email"
                            android:text="email"
                            android:fontFamily="sans-serif-light"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"/>

                    <EditText
                            android:id="@+id/text_email"
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:drawableLeft="@drawable/ic_email"
                            android:drawablePadding="10dp"
                            android:singleLine="true"
                            android:text="@={viewmodel.email}"
                            android:layout_marginBottom="10dp"
                            android:hint="john@gmail.com"
                            android:inputType="textEmailAddress"/>

                    <TextView
                            android:labelFor="@id/edit_text_password"
                            android:text="password"
                            android:fontFamily="sans-serif-light"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"/>

                    <EditText
                            android:drawablePadding="10dp"
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:singleLine="true"
                            android:text="@={viewmodel.password}"
                            android:id="@+id/edit_text_password"
                            android:drawableLeft="@drawable/ic_lock"
                            android:hint="Password"
                            android:inputType="textPassword"/>



                    <Button
                            android:id="@+id/button_sign_up"
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:layout_margin="22dp"
                            android:onClick="@{() -> viewmodel.signup()}"
                            android:background="#d67601"
                            android:text="Sign Up"
                            android:textAllCaps="false"
                            android:textColor="#fff"
                            android:textSize="18sp"/>

                    <TextView
                            android:id="@+id/text_view_register"
                            android:layout_gravity="center_horizontal"
                            android:textAppearance="@style/TextAppearance.AppCompat.Headline"
                            android:textAlignment="center"
                            android:onClick="@{(v) -> viewmodel.goToLogin(v)}"
                            android:text="Already have an account.nLogin Here"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"/>
                </LinearLayout>

            </RelativeLayout>

            <ImageButton
                    android:id="@+id/user_profile_photo"
                    android:layout_width="100dp"
                    android:layout_height="100dp"
                    android:layout_below="@+id/login_title"
                    android:layout_centerHorizontal="true"
                    android:layout_marginTop="16dp"
                    android:background="@drawable/user_profile_image_background"
                    android:elevation="4dp"
                    android:src="@drawable/ic_boy"/>

        </RelativeLayout>

        <ProgressBar
                android:id="@+id/progressbar"
                android:visibility="gone"
                android:layout_centerInParent="true"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>

    </RelativeLayout>

</layout>

  • This XML will generate the following design.
Firebase authentication mvvm
Firebase authentication mvvm

Again make sure that you have defined the correct path of the ViewModel inside the variable tag.

We have the design ready, and now all we need to do is bind ViewModel and View. But before doing this thing we need one more small thing. When authentication is successful we need to start HomeActivity and when the user logs out again we need to start LoginActivity. And we don’t want to repeat code again and again, so for both of these functions we’ll define two extension functions.

Tasks for switching between login and home activity

  • Create a new Kotlin file inside Useful Package and name it ViewUtils.kt.
fun Context.startHomeActivity() =
    Intent(this, HomeActivity::class.java).also {
        it.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        startActivity(it)
    }

fun Context.startLoginActivity() =
    Intent(this, LoginActivity::class.java).also {
        it.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        startActivity(it)
    }

  • We will use these functions for login and logout.
  • Now we can bind ViewModel and Activites but before doing so we will use codeine to create the dependency provider.

Creating a dependency provider using codeine

As you know, we should not make classes dependent. And to make the classes independent we need to use dependency injection patterns. And to do this we will use the codeine framework we already added.

  • So create a new class inside your main package called FirebaseApplication.
class FirebaseApplication : Application(), KodeinAware{

    override val kodein = Kodein.lazy {
        import(androidXModule(this@FirebaseApplication))

        bind() from singleton { FirebaseSource()}
        bind() from singleton { UserRepository(instance()) }
        bind() from provider { AuthViewModelFactory(instance()) }
        bind() from provider { HomeViewModelFactory(instance()) }

    }
}

  • Now we need to define this class in our AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools" package="net.simplifiedcoding">

    <application
            android:name=".FirebaseApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme" tools:ignore="AllowBackup,GoogleAppIndexingWarning">
        <activity android:name=".ui.home.HomeActivity">
        </activity>
        <activity android:name=".ui.auth.SignupActivity">
        </activity>
        <activity android:name=".ui.auth.LoginActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

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

</manifest>

  • And we are done.

Binding Viewmodel and Activities

Loginactivity

  • Open LoginActivity and write the following code.
class LoginActivity : AppCompatActivity(), AuthListener, KodeinAware {

    override val kodein by kodein()
    private val factory : AuthViewModelFactory by instance()


    private lateinit var viewModel: AuthViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding: ActivityLoginBinding = DataBindingUtil.setContentView(this, R.layout.activity_login)
        viewModel = ViewModelProviders.of(this, factory).get(AuthViewModel::class.java)
        binding.viewmodel = viewModel

        viewModel.authListener = this
    }

    override fun onStarted() {
        progressbar.visibility = View.VISIBLE
    }

    override fun onSuccess() {
        progressbar.visibility = View.GONE
        startHomeActivity()
    }

    override fun onFailure(message: String) {
        progressbar.visibility = View.GONE
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }

    override fun onStart() {
        super.onStart()
        viewModel.user?.let {
            startHomeActivity()
        }
    }
}

  • The code is very simple and straightforward, if you are having trouble understanding anything, please comment.

Signup activity

  • Now we will do the same thing inside SignupActivity.
class SignupActivity : AppCompatActivity(), AuthListener, KodeinAware {

    override val kodein by kodein()
    private val factory : AuthViewModelFactory by instance()

    private lateinit var viewModel: AuthViewModel

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

        val binding: ActivitySignupBinding = DataBindingUtil.setContentView(this, R.layout.activity_signup)
        viewModel = ViewModelProviders.of(this, factory).get(AuthViewModel::class.java)
        binding.viewmodel = viewModel

        viewModel.authListener = this
    }

    override fun onStarted() {
        progressbar.visibility = View.VISIBLE
        Intent(this, HomeActivity::class.java).also {
            it.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            startActivity(it)
        }
    }

    override fun onSuccess() {
        progressbar.visibility = View.GONE
        startHomeActivity()
    }

    override fun onFailure(message: String) {
        progressbar.visibility = View.GONE
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }
}

  • Now we just need to work on homeactivity.

Ending home activity

Creating HomeViewModel and HomeViewModelFactory

  • Make first HomeViewModel Inside the home package.
class HomeViewModel(
    private val repository: UserRepository
) : ViewModel() {

    val user by lazy {
        repository.currentUser()
    }
    
    fun logout(view: View){
        repository.logout()
        view.context.startLoginActivity()
    }
}

  • Again we need to create our ViewModelFactory as we are passing the repository to HomeViewModel. So create another class named HomeViewModelFactory.
@Suppress("UNCHECKED_CAST")
class HomeViewModelFactory(
    private val repository: UserRepository
) : ViewModelProvider.NewInstanceFactory() {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return HomeViewModel(repository) as T
    }

}

  • And all. Let us now code the XML part of our homeactivity.

Designing UI

  • go inside activity_home.xml And write the following code.
<?xml version="1.0" encoding="utf-8"?>
<layout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="viewmodel"
                  type="net.simplifiedcoding.ui.home.HomeViewModel"/>
    </data>

    <RelativeLayout
            android:id="@+id/drawer_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".ui.home.HomeActivity">

            <TextView
                    android:text="@{viewmodel.user.email}"
                    tools:text="probelalkhan@gmail.com"
                    android:textAppearance="@style/TextAppearance.AppCompat.Headline"
                    android:layout_centerInParent="true"
                    android:id="@+id/textViewEmail"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"/>

            <Button
                    android:onClick="@{(v) -> viewmodel.logout(v)}"
                    android:text="Logout"
                    android:layout_centerHorizontal="true"
                    android:layout_below="@id/textViewEmail"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"/>

    </RelativeLayout>

</layout>

  • Again make sure that you have given the correct path to the HomeViewModel inside the variable tag.

Binding HomeViewModel and HomeActivity

  • Again we will do the same thing that we did for the login and signup activity.
class HomeActivity : AppCompatActivity(), KodeinAware {

    override val kodein by kodein()
    private val factory : HomeViewModelFactory by instance()

    private lateinit var viewModel: HomeViewModel

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

        val binding: ActivityHomeBinding = DataBindingUtil.setContentView(this, R.layout.activity_home)
        viewModel = ViewModelProviders.of(this, factory).get(HomeViewModel::class.java)
        binding.viewmodel = viewModel

    }

}

  • And we are done. You can try running the application and it should work fine. For example, if you are not working then you can check my apk.

Download apk

Firebase mvvm example source code

If you are not able to follow through the tutorial, do not worry about having source code for me to check your project. And if there is still problem comment below and I will try to help you.


Git hub repository
Get source code

So that’s it for Firebase mvvm example friend. I hope I have taught you something new with this post. And if you think this is really useful, please support me by sharing this post with your friends. Thank you 4


Source link

About dmtechnolab

Check Also

Simplified Coding

Android Espresso Tutorial – Testing Fragment in Isolation – Android Coding by DMTechnolab

Welcome to another tutorial in the Android test series. And this post is called Android …

Leave a Reply

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