Lesson Tuesday

We can now register new users, and Firebase authenticates their account automatically. The next logical step is ensuring they can log themselves back out (and eventually back in). In this lesson we'll address how to create additional menu options and easily un-authenticate a user's session using Firebase.

Overflow Menu

First off, we'll need an option or button users may click to log themselves out. Let's place this in an overflow menu. Overflow menu is the name for the additional options displayed when the icon with three vertical dots is clicked.

new-dots-in-main-activity-menu

For now, we'll inflate our overflow menu in the MainActivity:

Creating and Inflating an Overflow Menu

To create our new menu's layout file, first we'll right-click in the res directory, and add a new resource directory called menu of type menu. Then, we'll right-click on the menu directory and select New > Menu resource file.

Let's name this file menu_main.xml, and place the following code inside:

menu_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_logout"
        android:title="Logout"
        android:visible="true"
        app:showAsAction="never" />
</menu>

Just as we did when creating our SearchView widget, we'll inflate our new menu in an onCreateOptionsMenu() method within MainActivity:

MainActivity.java
...
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);
        return super.onCreateOptionsMenu(menu);
    }
...

Next, we'll need to tell our app what action to perform when the user selects the logout option. We'll do this by adding the following code to an onOptionsItemSelected() override:

MainActivity.java
...
 @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_logout) {
            logout();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
...

At the moment, we only have one menu action item. But we may want to add more options in the future. Therefore, we'll include a conditional that only calls logout() if the logout option was specifically selected, similar to the manner we organize our onClick() methods that correspond to the View.OnClickListener interface.

Let's create the logout() method now:

MainActivity.java
...
private void logout() {
        FirebaseAuth.getInstance().signOut();
    }
...

Pretty straightforward! Here, we simply call Firebase's getInstance() method on our FirebaseAuth object. Then, we can then use Firebase's built-in signOut() method to sign the user out of their session.

Returning to MainActivity on Logout

Remember, we decided users must log in before interacting with our app. That way, any restaurants they save can be associated with their own, personal list in our database. With this in mind, let's return users to the LoginActivity after logging out.

We'll add the following code to our existing logout() method in MainActivity:

MainActivity.java
...
private void logout() {
        FirebaseAuth.getInstance().signOut();
        Intent intent = new Intent(MainActivity.this, LoginActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
        finish();
    }
...

Here, we create a new Intent to return the user to the LoginActivity, add flags to remove the current activity from our stack, start the new Intent, and end the current instance of MainActivity with the finish() method.

Updating MainActivity Layout

Now, we won't be able to see the logout option in our overflow menu quite yet. There's still one more step we must complete. Several weeks ago, we hid the app bar in the MainActivity of MyRestaurants (as seen in this lesson) because we simply didn't have any menu options to display yet. Now that we do, we'll need to remove the "NoActionBarTheme" previously applied to the MainActivity.

We can do this by removing the following line from MainActivity's entry in AndroidManifest.xml:

android:theme="@style/NoActionBarTheme"

The updated AndroidManifest.xml file should look like this:

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

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".ui.MainActivity">
        </activity>
        <activity android:name=".ui.RestaurantListActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".ui.MainActivity" />
        </activity>
        <activity android:name=".ui.RestaurantDetailActivity" />
        <activity android:name=".ui.SavedRestaurantListActivity" />
        <activity android:name=".ui.CreateAccountActivity" />
        <activity android:name=".ui.LoginActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Now, if we launch our application we should see three dots in our MainActivity's AppBar that indicate an overflow menu is available:

new-dots-in-main-activity-menu

If we click this icon the overflow menu is expanded, and we can see our new "Logout" option:

log-out-overflow-menu

Clicking this will log the current user out of their session, and return them to the LoginActivity. Try it out!


Example GitHub Repo for MyRestaurants

Terminology


  • Overflow menu: The name for the additional options displayed when the icon with three vertical dots is clicked, as seen below:

new-dots-in-main-activity-menu

Overview


  • FirebaseAuth.getInstance().signOut(); is the general way to un-authenticate a Firebase user session.

Creating and Using Menus

Right-click on the menu directory and select New > Menu resource file. Populate the layout with the necessary XML:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_logout"
        android:title="Logout"
        android:visible="true"
        app:showAsAction="never" />
</menu>

Inflate the menu in an onCreateOptionsMenu() method within the corresponding activity:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);
        return super.onCreateOptionsMenu(menu);
    }

Instruct the app what action to perform when the user selects menu option(s) by adding code to an onOptionsItemSelected() override in the corresponding activity:

 @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_logout) {
            logout();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

Examples