Lab 4 - Authentication API
- 📝 Worth: 3%
- 📅 Due: Friday April 12, 2024 @End of class
- 🕑 Late submissions: Not accepted.
- 📥 Submission: In class
Objectives
In this lab, we will learn about authentication API to help you setup a similar mechanism in the final project.
- Learn how to setup an authentication API
- Learn how to use it in a MAUI project
- Learn more about the
IConnectivity
interface - Learn more about authentication and connectivity exception handling.
Authentication
Authentication is the process of validating the identity of a registered user or process before providing access to protected resources, networks or systems. It is a well studied problem in the domain of information security. Many protocols have been developed to standardize the process.
OAuth
is an open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications. It enables sharing data across APIs without having to share a password. As matter of fact, OAuth
2.0 is the industry protocol for authorization. It allows a user to grant limited access to its protected resources.
Many APIs use OAuth
to provide authentication services to programmers to be able to build app with ease. Here are some of the common APIs that use OAuth:
- Firebase by Google.
- Azure Authentication by Microsoft.
- Auth0 (https://auth0.com/)
In this lab, we will examine Firebase Authentication
and use it to authenticate users to use our MauiFitness
app. Feel free to use any API in the project.
Setup
-
Use your section’s GitHub classroom link:
-
Accept the assignment Clone this repo locally
-
In the
MauiFitness
app, I have already added an"appsettings.json"
file and included it as an embedded file -
I also added a
Settings
class to parse all the configuration strings into a staticSettings
class -
Use this class to add any new API key you will be using for this lab. Note: This is also how you should parse settings within your project.
Meals and workout Apis keys:
-
Let’s add API keys used by the
WorkoutService
andMealService
class -
Create an https://api-ninjas.com/ account
-
Go into MyAccount
-
Click Show API Key
-
Copy this API key
-
Add the following fields in
appsettings.json
and in the associated classConfig.Settings.cs
CaloriesApiKey: Your API key
CaloriesApiUrl
:"https://api.api-ninjas.com/v1/nutrition?query="
ActivitiesApiKey: Your API key
ActivitiesApiUrl
:"https://api.api-ninjas.com/v1/caloriesburned?activity="
Firebase authentication Api key:
- Go to https://console.firebase.google.com/
- Login using a Google account (no need to create a new account)
- In the welcome page, click on
Create a project
- Project Name: MauiFitness
- Disable Google Analytics for this project, we will not use them.
- Click
Create Project
- Setting Authentication
- Once the project is created, you will land in the main Firebase dashboard.
- Scroll down and click on the
Authentication
block. - Click on
Get Started
to enable authentication and display the list of providers. - Firebase Authentication provides backend services, easy-to-use SDKs, and ready-made UI libraries to authenticate users to your app. It supports authentication using passwords, phone numbers, popular federated identity providers like Google, Facebook and Twitter, and more.
- In this lab, we will utilize it with a native provider via
Email/Password
. - Click
Email/Password
>Enable
>Save
- The
MauiFitness
app does not include a registration functionality, so we will need to create user accounts manually. - Go to the
Users
tab - Add two users manually:
- First user: an account for you (add your email and a password)
- Second user: for the teacher to access your app
- email: teacher@jac.ca
- password: test@1234
Notes for the Project
- As you may have noticed, Firebase provides options for the user to sign up with an email address or via an email link. You may use any of the options for the project.
- You may use other providers such as Google as well.
- Feel free to use pre-built UI libraries for login and registration pages.
Adding the keys to Settings
and appsettings.json
-
Add the following values as public variables
-
FirebaseAuthorizedDomain
- Get value from Firebase portal > Go to the
Settings
tab (while being in Authentication) - Under Authorized domains > copy the Firebase App domain (usually second entry)
Example:
mauifitness-?????.firebaseapp.com
- Get value from Firebase portal > Go to the
-
FirebaseApikey
- Get value from Firebase portal > Left Navigation > Click on the gear icon ⚙️ next to
Project Overview
- Select
Project Settings
> UnderGeneral
tab > Web API Key
- Get value from Firebase portal > Left Navigation > Click on the gear icon ⚙️ next to
-
Preparing App to use Firebase API
-
Right-click on the solution and choose
Manage NuGet Packages
- Go to
Browse
tab > Search forFirebaseAuthentication.net
. - Install latest version
4.1.0
. (Tested to be working withMAUI
&.NET 7.0
)
- Go to
-
In the existing
Services
folder-
Create a class
AuthService
that will use the authentication we have setup on Firebase portal. -
As discuss earlier, we will only use an
EmailProvider
for authentication. We need to create a client that accepts an email provider.- The code below is based on the NuGet package documentation sample code.
- Check the sample code as it provides pre-built login webpage, which includes a registration link and possibility to login with any of the 3rd party providers.
public class AuthService { // Configure... private static FirebaseAuthConfig config = new FirebaseAuthConfig { ApiKey = App.Settings.FireBaseApiKey, AuthDomain = App.Settings.FireBaseAuthDomain, Providers = new FirebaseAuthProvider[] { // Add and configure individual providers new EmailProvider() }, }; // ...and create your FirebaseAuthClient public static FirebaseAuthClient Client { get; } = new FirebaseAuthClient(config); public static UserCredential UserCreds { get; set; } }
-
-
Go to
LoginPage.xaml.cs
to update the login button click event to use Firebase authentication class.-
Authentication process is an IO bound call and prone to errors.
-
Will fail if a wrong password or wrong username are provided.
-
Will fail is wrong API key is used and several other.
-
Make sure to use a
try
-catch
blocks.- Add multiple
catch
blocks each for specific exception type. - Start with more specific exception, then the general one.
- Firebase exception type is
FirebaseAuthException
which has aReason
property which contains the reason of failure. - Log the
Reason
in the console - Display an alert with a description of the error.
try { ... } catch (FirebaseAuthException ex) { ... } catch (OtherExceptionType ex) { ... } catch (Exception ex) { ... }
- Add multiple
-
Check if internet connectivity is available. Authentication will fail if there is no internet.
.NET MAUI App
Connectivity documentation.
-
-
The
FirebaseAuthClient
(used in theAuthService
class) provides different methods to assist in the login process:SignInWithEmailAndPasswordAsync(user_name.Text, password.Text)
attempt to login using the provided username and password.- Check the sample code on GitHub.
-
Once authenticated make sure to save the returned
UserCredential
in theUseCreds
property in theAuthService
class. We need to use the authentication later to access the database.- Display an alert if the login was successful.
- Display the exception message if an error occurred.
-
-
Test app while adding debug points to ensure that the authentication is done successfully.
Change Login Page Behavior
Currently the login page is a tab and will not prevent the user from accessing the app. We need to change the behavior to have a landing page, which is the login page. Once logged in, we navigate to the app tabs.
- The app should have only two navigation routes:
Login
andHome
(the app tabs). - Head to
AppShell.xaml
to make the changes:
<Shell ...>
<!-- Landing Page -->
<ShellContent Route="Login" ContentTemplate="{DataTemplate views:LoginPage}" />
<!-- App Tabs: note the use of FlyoutDisplayOptions="AsMultipleItems" -->
<TabBar Route="Index" FlyoutDisplayOptions="AsMultipleItems">
<ShellContent Title="Workouts" ContentTemplate="{DataTemplate views:WorkoutsPage}"
Icon="gym.png"/>
<!-- Add the other tab pages .... -->
<!-- Add the login page to be used to display account info and to logout-->
<ShellContent Title="Account" ContentTemplate="{DataTemplate views:LoginPage}"
Icon="home.png"/>
</TabBar>
</Shell>
- In the above setup, the
LoginPage.xaml
is used twice. We need to insure that only a single instance of it is created.- Go to
MauiProgram.cs
to register a singleton of theLoginPage
and all the other pages since we only need a single instance of each. .Net Maui
provides a built-in functionality to usedependency injection
by either creating singleton or transient instance of a class. This functionality is similar to the one you used inAsp .Net
.- When object is created as a
Singleton
, the app will create a single instance of the object which will be remain for the lifetime of the application. - When object is created as a
Transient
, a new instance of the object will be created when requested during resolution. Transient objects do not have a pre-defined lifetime, but will typically follow the lifetime of their host.
- When object is created as a
- The
builder
object has aServices
property that to register any object that is needed in app.- Depending on the needs of your application, you may need to add services with different lifetimes, either singleton or transient.
AddSingleton<T>
AddTransient<T>
- Depending on the needs of your application, you may need to add services with different lifetimes, either singleton or transient.
- Go to
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
...
builder.Services.AddSingleton<LoginPage>();
builder.Services.AddSingleton<WorkoutsPage>();
builder.Services.AddSingleton<MealsPage>();
builder.Services.AddSingleton<MeasuresPage>();
return builder.Build();
}
Check
.Net Maui
dependency injection documentation for more details.
-
On a successful login, navigate from the landing page, the login page, to the App.
-
Go to
LoginPage.xaml.cs
-
The App route is
Home
, add a navigation call once successfully logged in the button event handler.await Shell.Current.GoToAsync($"//Index");
-
-
App is ready for testing.
- Run the app.
- You should be presented with the login page (with no tabs at the bottom)
- Enter the username and password, then click the login button.
- If the login was successful, you should get an alert and would be redirected to the app with tabs.


✨ Test your understanding: For the project, how can you customize the pages that appear to the user based on who they are?
Logout Functionality
-
The login page is used to provide the username and password.
-
It will be used to add a logout functionality as well.
-
Apply the following UI addition\modifications to the
LoginPage.xaml
:- Login Container: wrap the entries for the username and password, the login image button and error label with a container, such as
Frame
,StackLayout
or aGrid
and provide it with anx:Name
value.- You might have already have it from milestone 1.
- Logout Container: add another container below the above container that includes the following:
- A label to display the user details.
- A button to logout with a click event handler.
- Assign an
x:Name
value to the container. - Hide the container by using
IsVisible="false"
- Login Container: wrap the entries for the username and password, the login image button and error label with a container, such as
-
In
LoginPage.xaml.cs
-
Modify the login button click event handler to do the following:
- On a successful login:
- Set the visibility of the login container to
false
to hide it. - Set the visibility of the out container to
true
to display it on the page.- Display the username and user ID (using
AuthService.UserCreds.User.Uid
)
- Display the username and user ID (using
- Set the visibility of the login container to
- On a successful login:
-

In the logout button click event handler:
-
- Use the
Client
property to logoutAuthService.Client.SignOut()
- Clear the username and password entry fields.
- Swap the containers visibility to show the login container and hide the logout container.
- Finally, navigate to the login page using the route
await Shell.Current.GoToAsync($"//Login");
- Use
try
-catch
blocks to catch any possible exception.
- Use the
-
Test the login and logout functionality of the app.
- Login using the created username and password.
- Go to the last tab
Account
. - Click Logout.
- The app should navigate to the login page. (tabs will not be available after you logout)