Xamarin.Forms and Firebase – Authentication

Firebase is part of a growing trend known as “Back-end as a service”. Firebase has 8 technologies that are designed to enhance your app development experience, including Firebase authentication, Realtime Database, Cloud Storage, …

In this post where are going to look at Firebase authentication.

What is Firebase Authentication?

Firebase Authentication is an easy API that will allow you to use sign in from federated providers, a simple email/password scheme, or integrate with any authentication back ends you own. It integrates with other Firebase services such as Realtime database, so you can control who accesses what data.

Configuring Firebase

First of all, we are going to configure Firebase. Go to https://console.firebase.google.com and click on Create a project.

Welcome to Firebase! 
Tools from Google for building app infrastructure, improving app quality 
and growing your business 
Create a project 
— View docs

Give your project a name and follow the wizard.

Adding the Android and iOS project

First register the Android application and download the google-services.json file.

Then register the iOS application and download the GoogleService-Info.plist.

Configuring Authentication

Go to the authentication section and then to Sign-in method. Here enable Email/Password. Then create a user under the tab Users.

Xamarin.Forms application

Xamarin.Forms Configuration

Android

In the Android project, add the NuGet packages Xamarin.Firebase.Auth and Xamarin.Firebase.Core. Be sure to add the version 60.1142.1 because in the later version is a bug that the Authentication instance always stays null.

Add the google-services.json file to the project and set the building action to GoogleServicesJson. To do this, make the following change in the .csproj file of this project.

<ItemGroup>
    <GoogleServicesJson Include="google-services.json"/>
</ItemGroup>

Make sure your package name in the project is identical to the package name inside “google-services.json”. You find the package name in the project properties under Android Manifest.

Initialize Firebase authentication in MainActivity. Add the line FirebaseApp.InitializeApp(Application.Context); before LoadApplication(new App());

iOS

In the iOS project, add the NuGet package Xamarin.Firebase.iOS.Auth.

Import the GoogleService-Info.plist file and set the building action to BundleResource. As in the Android-project, make sure that the Bundle identifier in the Info.plist is identical to the bundle identifier inside GoogleService-Info.plist.

Initialize Firebase authentication in AppDelegate by adding the line Firebase.Core.App.Configure(); before LoadApplication(new App());

Adding the authentication

There are only platform specific Xamarin.Firebase NuGet packages, we have to create an interface that we implement in the platform specific projects.

The interface will look like this.

public interface IFirebaseAuthentication
{
    Task<string> LoginWithEmailAndPassword(string email, string password);
    bool SignOut();
    bool IsSignIn();
}

The Android implementation:

public class FirebaseAuthentication : IFirebaseAuthentication
{
    public bool IsSignIn()
    {
        var user = Firebase.Auth.FirebaseAuth.Instance.CurrentUser;
        return user != null;
    }

    public async Task<string> LoginWithEmailAndPassword(string email, string password)
    {
        try
        {
            var user = await Firebase.Auth.FirebaseAuth.Instance.SignInWithEmailAndPasswordAsync(email, password);
            var token = await user.User.GetIdTokenAsync(false);
            return token.Token;
        }
        catch (FirebaseAuthInvalidUserException e)
        {
            e.PrintStackTrace();
            return string.Empty;
        }
        catch (FirebaseAuthInvalidCredentialsException e)
        {
            e.PrintStackTrace();
            return string.Empty;
        }
    }

    public bool SignOut()
    {
        try
        {
            Firebase.Auth.FirebaseAuth.Instance.SignOut();
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }
}

The iOS implementation:

public class FirebaseAuthentication : IFirebaseAuthentication
{
    public bool IsSignIn()
    {
        var user = Auth.DefaultInstance.CurrentUser;
        return user != null;
    }

    public async Task<string> LoginWithEmailAndPassword(string email, string password)
    {
        var user = await Auth.DefaultInstance.SignInWithPasswordAsync(email, password);
        return await user.User.GetIdTokenAsync();
    }

    public bool SignOut()
    {
        try
        {
            _ = Auth.DefaultInstance.SignOut(out NSError error);
            return error == null;
        }
        catch (Exception)
        {
            return false;
        }
    }
}

Make the MainPage and the LoginPage. You can find the code on my Github.

When you now run the application, you will get the login screen. When you enter your email and password, you will be redirected to the MainPage, where you get a text that you’re logged in and a sign-out button. If something goes wrong, you will see a dialog telling you that authentication failed.

Screenshots from the application:

In this article, we saw how we can implement Firebase Authentication in our Xamarin.Forms application and that this is relatively simple to do.

Lindsey is a .NET Consultant at eMenKa NV where she is focusing on web development. She is a crew-member of Techorama Belgium and the Netherlands and she runs VISUG, The Visual Studio User Group in Belgium.
8 comments
  1. Hello Lindsey,
    thanks for your great post. I followed all steps, but something goes wrong.
    As soon as the method Auth.DefaultInstance.SignInWithPasswordAsync(email, password) is triggered, I get the following error:

    Firebase.FirebaseNetworkException: ‘A network error (such as timeout, interrupted connection or unreachable host) has occurred.’

    I followed your steps 100%, including the following:
    – the user I use for testing has been created in the Authentication tab of my Firebase project
    – email login is enabled in Firebase
    – the FirebaseApp is initialized in the MainActivity
    – the correct NuGet packages are installed
    – …

    Do you maybe have an idea what could have caused this error?
    I already included the following permissions to the AndroidManifest:

    I realized that Firebase does not seem to get a connection request at all from my app, because the SDK setup when registering my app on Firebase stops at step 4 (execute app to check installation) and it does not seem to recognize any communication with the Firebase servers.

    I was thinking if this is maybe due to some firewall settings or other internet configurations blocking this connection?

    Thank you very much for your help in advance.

  2. Excuse me, how can i do a Signup() ?

  3. @Deemotion Please Search Google Firebase Authentication for Web

  4. Dear Lindsey

    My name is Majid. I am designing an App to be used in my teaching. I am a school teacher.

    I am using Xamarin.forms and Firebase database

    I want to signup with three entry fields
    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace CompuChemApp.Models
    {
    public class Users
    {
    public string Email { get; set; }
    public string Password { get; set; }
    public DateTime ExpiryDate { get; internal set; }
    }
    }

    The ExpiryDate is to be set automatically. The user does not input it. It should be part of the code

    During Login, a user needs just to enter two fields (email and password) while the third field will the DateTime.Now

    If the login time is before the ExpiryDate, the user will be able to login
    If Not, the user will be denied the use of the app

    I wrote the following code which is NOT doing what i want it to do.

    using System.ComponentModel;
    using Xamarin.Forms;
    using CompuChemApp.View;
    using System;
    using System.Diagnostics;

    namespace CompuChemApp.ViewModel
    {
    public class LoginViewModel : INotifyPropertyChanged
    {
    private int res;

    public event PropertyChangedEventHandler PropertyChanged;

    public LoginViewModel()
    {

    }
    private string email;

    public string Email
    {
    get { return email; }
    set
    {
    email = value;
    PropertyChanged(this, new PropertyChangedEventArgs(“Email”));
    }
    }

    private string password;
    public string Password
    {
    get { return password; }
    set
    {
    password = value;
    PropertyChanged(this, new PropertyChangedEventArgs(“Password”));
    }
    }

    private DateTime expiryDate;

    public DateTime ExpiryDate
    {
    get { return expiryDate; }
    set
    {
    expiryDate = value;
    PropertyChanged(this, new PropertyChangedEventArgs(“ExpiryDate”));
    }
    }

    public Command LoginCommand
    {
    get
    {
    return new Command(Login);
    }
    }
    public Command SignUp
    {
    get
    {
    return new Command(() => { App.Current.MainPage.Navigation.PushAsync(new XF_SignUpPage()); });
    }
    }

    public Command DeleteCommand
    {
    get { return new Command(Delete); }
    }

    //public Command UpdateCommand
    //{
    // get { return new Command(Update); }
    /// }

    private async void Delete()
    {
    try
    {
    var isdelete = await FirebaseHelper.DeleteUser(Email);
    if (isdelete)
    await App.Current.MainPage.Navigation.PopAsync();
    else
    await App.Current.MainPage.DisplayAlert(“Error”, “Record not deleted”, “Ok”);
    }
    catch (Exception e)
    {

    Debug.WriteLine($”Error:{e}”);
    }
    }

    //private async void Update()
    //{
    // try
    // {
    // if (!string.IsNullOrEmpty(Password))
    // {
    // var isupdate = await FirebaseHelper.UpdateUser(Email, Password, ExpiryDate);
    // if (isupdate)
    // await App.Current.MainPage.DisplayAlert(“Update Success”, “”, “Ok”);
    // else
    // await App.Current.MainPage.DisplayAlert(“Error”, “Record not updated”, “Ok”);
    // }
    // else
    // await App.Current.MainPage.DisplayAlert(“Password Required”, “Please Enter your password”, “Ok”);
    // }
    // catch (Exception e)
    // {

    // Debug.WriteLine($”Error:{e}”);
    // }
    // }

    private async void Login()
    {
    ///LoginDate.Text = DateTime.Now.ToString(); //// (“dddd, dd MMMM yyyy HH:mm:ss”);

    //null or empty field validation, check weather email and password is null or empty

    if (string.IsNullOrEmpty(Email) || string.IsNullOrEmpty(Password))
    await App.Current.MainPage.DisplayAlert(“Empty Values”, “Please enter Email and Password”, “OK”);
    else
    {
    //call GetUser function which we define in Firebase helper class
    var user = await FirebaseHelper.GetUser(Email);

    DateTime dateTime1 = expiryDate;
    var d1 = dateTime1;

    DateTime d2 = user.ExpiryDate;

    res = DateTime.Compare(d1, d2);

    //firebase return null valuse if user data not found in database
    if (user != null)
    if (Email == user.Email && Password == user.Password && res < 0)
    {

    await App.Current.MainPage.DisplayAlert("Login Success", "", "Ok");
    //Navigate to Wellcom page after successfuly login
    //pass user email to welcom page
    await App.Current.MainPage.Navigation.PushAsync(new WelcomPage(Email));
    }
    else
    await App.Current.MainPage.DisplayAlert("Login Fail", "Please enter correct Email and Password or The App has Expired!", "OK");
    else
    await App.Current.MainPage.DisplayAlert("Login Fail", "User not found", "OK");

    }
    }
    }
    }

    CAN YOU HELP ME PLEASE???

  5. Hi, I follow your instructions and my iOS app crash with when it pass through this code
    var user = await Auth.DefaultInstance.SignInWithPasswordAsync(email , password);
    It’s just said The app have been terminated

  6. seems like firebase auth has changed since this code was posted.

    i can no longer use
    var token = await user.User.GetIdTokenAsync(false);
    in the latest version.

    the following call also hangs even though the account has been created in the firebase console….
    var user = await Firebase.Auth.FirebaseAuth.Instance.SignInWithEmailAndPass….

  7. GetIdTokenAsync(false) it’s not used anymore just use
    var token = await user.User.GetIdToken(false);
    Also is better to init Firebase in MainActivity like this:
    var options = new FirebaseOptions.Builder()
    .SetApplicationId(“authdemo-4bf05”)
    .SetApiKey(“AIzaSyAFutzPlCF1WnTvxbQoq7pHGUfjDbfvTPM”)
    .SetStorageBucket(“authdemo-4bf05.appspot.com”).Build();
    var fapp = FirebaseApp.InitializeApp(this, options);
    Before LoadApplication(new App()); like Lindsey said;
    Have fun

  8. This was very helpful, thanks a lot.

Leave a Reply

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