Skip to main content
← Blog
Desarrollo

Firebase for Xamarin.Forms — Part 1: FirebaseAuth for Android

5 min read
Firebase for Xamarin.Forms — Part 1: FirebaseAuth for Android

Following the introduction article where we outlined what we’d build, we start the implementation today — focusing on Firebase authentication for the Android side of our Xamarin.Forms app.

Starting point

We’ll begin from a Xamarin.Forms project structured with MVVM, containing a login screen, a registration screen, and a main screen accessible only after login. Download the initial project from GitHub: https://github.com/jamontes79/xamarin-forms-firebase-sample/tree/02e843e9f06e467f454cd49b9cd0f5b00f14c995

Firebase Console setup

Go to https://firebase.google.com and create a new project. Once it’s created, click “Add Firebase to your Android app.”

The key fields:

  • Android package name — your unique app identifier
  • App nickname — optional, just for the console
  • Debug signing certificate SHA-1 — important for Google Sign-In; use a different Firebase project for debug vs. release

To get the debug certificate SHA-1:

Mac:

keytool -list -v -keystore ~/.local/share/Xamarin/Mono\ for\ Android/debug.keystore \
  -alias androiddebugkey -storepass android -keypass android

Windows:

keytool.exe -list -v \
  -keystore "%LocalAppData%\Xamarin\Mono for Android\debug.keystore" \
  -alias androiddebugkey -storepass android -keypass android

Download the google-services.json file — you’ll need it shortly.

Configuring authentication methods

In the Firebase console sidebar, click Authentication → Sign-in method. Enable:

  1. Email/Password
  2. Google — when you enable this, note down the Web client ID. You’ll need it later.

Setting up the project

Install the required NuGet packages in your Android project. Search for and install:

  • Google Play Services (includes Firebase Auth)

Adding google-services.json

Add the google-services.json file to the root of your Android project and set its build action to GoogleServicesJson. (If that option doesn’t appear, close and reopen the solution.)

Then add the Google Play Services Auth NuGet package to enable Google Sign-In.

Implementing the code

Since we’re using a PCL, we’ll use dependency injection throughout.

Initializing Firebase

In MainActivity:

public static FirebaseApp app;

protected override void OnCreate(Bundle bundle) {
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;
    base.OnCreate(bundle);
    InitFirebaseAuth();
    UserDialogs.Init(this);
    global::Xamarin.Forms.Forms.Init(this, bundle);
    LoadApplication(new App());
}

private void InitFirebaseAuth() {
    var options = new FirebaseOptions.Builder()
        .SetApplicationId("1:2485447395:android:1bf7180db061f771")
        .SetApiKey("AIzaSyBdszK9ZCwbukS8Qb1iZ_LCXVq2os-KYJA")
        .Build();

    if (app == null)
        app = FirebaseApp.InitializeApp(this, options, "FirebaseSample");
}

The Application ID and API Key come from the Firebase console under your project settings.

Service interface (shared project)

using System;
using System.Threading.Tasks;

namespace firebasesample.Services.FirebaseAuth {
    public interface IFirebaseAuthService {
        String getAuthKey();
        bool IsUserSigned();
        Task<bool> SignUp(String email, String password);
        Task<bool> SignIn(String email, String password);
        void SignInWithGoogle();
        Task<bool> SignInWithGoogle(String token);
        Task<bool> Logout();
    }
}

Android service implementation

public class FirebaseAuthService : IFirebaseAuthService {
    public bool IsUserSigned() {
        var user = Firebase.Auth.FirebaseAuth.GetInstance(MainActivity.app).CurrentUser;
        return user != null;
    }

    public async Task<bool> SignIn(string email, string password) {
        try {
            await Firebase.Auth.FirebaseAuth.GetInstance(MainActivity.app)
                .SignInWithEmailAndPasswordAsync(email, password);
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    public async Task<bool> SignUp(string email, string password) {
        try {
            await Firebase.Auth.FirebaseAuth.GetInstance(MainActivity.app)
                .CreateUserWithEmailAndPasswordAsync(email, password);
            return true;
        } catch (Exception ex) {
            return false;
        }
    }

    public async Task<bool> Logout() {
        try {
            Firebase.Auth.FirebaseAuth.GetInstance(MainActivity.app).SignOut();
            return true;
        } catch (Exception ex) {
            return false;
        }
    }
}

Google Sign-In

Create a GoogleLoginActivity that shows the Google account picker:

protected override void OnCreate(Bundle savedInstanceState) {
    base.OnCreate(savedInstanceState);

    GoogleSignInOptions gso = new GoogleSignInOptions
        .Builder(GoogleSignInOptions.DefaultSignIn)
        .RequestIdToken("2485447395-g5sdqpgfdjklgo2f1ir84s0cedsdqgv1.apps.googleusercontent.com")
        .Build();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
        .AddConnectionCallbacks(this)
        .AddOnConnectionFailedListener(this)
        .AddApi(Auth.GOOGLE_SIGN_IN_API, gso)
        .Build();

    Intent signInIntent = Auth.GoogleSignInApi.GetSignInIntent(mGoogleApiClient);
    StartActivityForResult(signInIntent, RC_SIGN_IN);
}

The token in RequestIdToken is the Web client ID you noted when enabling Google Sign-In.

In MainActivity, add OnActivityResult to handle the result from GoogleLoginActivity:

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) {
    base.OnActivityResult(requestCode, resultCode, data);
    if (requestCode == FirebaseAuthService.REQ_AUTH && resultCode == Result.Ok) {
        GoogleSignInAccount sg = (GoogleSignInAccount)data.GetParcelableExtra("result");
        MessagingCenter.Send(FirebaseAuthService.KEY_AUTH,
                             FirebaseAuthService.KEY_AUTH,
                             sg.IdToken);
    }
}

Back in the service, the Google Sign-In methods:

public void SignInWithGoogle() {
    var googleIntent = new Intent(Forms.Context, typeof(GoogleLoginActivity));
    ((Activity)Forms.Context).StartActivityForResult(googleIntent, REQ_AUTH);
}

public async Task<bool> SignInWithGoogle(string token) {
    try {
        AuthCredential credential = GoogleAuthProvider.GetCredential(token, null);
        await Firebase.Auth.FirebaseAuth.GetInstance(MainActivity.app)
            .SignInWithCredentialAsync(credential);
        return true;
    } catch (Exception ex) {
        return false;
    }
}

Wiring the ViewModel

In the LoginViewModel constructor:

private IFirebaseAuthService _firebaseService;

public LoginViewModel(IUserDialogs userDialogsService) {
    _userDialogService = userDialogsService;
    _firebaseService = DependencyService.Get<IFirebaseAuthService>();
    MessagingCenter.Subscribe<String, String>(this, _firebaseService.getAuthKey(),
        (sender, args) => { LoginGoogle(args); });
}

Login methods:

private async Task LoginCommandExecute() {
    if (await _firebaseService.SignIn(Username, Password)) {
        await NavigationService.NavigateToAsync<MainViewModel>();
    } else {
        _userDialogService.Toast("Incorrect username or password");
    }
}

private async Task LoginGoogleCommandExecute() {
    _firebaseService.SignInWithGoogle();
}

private async Task LoginGoogle(String token) {
    if (await _firebaseService.SignInWithGoogle(token)) {
        await NavigationService.NavigateToAsync<MainViewModel>();
    }
}

To navigate directly to the main screen when the user is already signed in, update InitializeAsync in NavigationService:

public Task InitializeAsync() {
    var _firebaseService = DependencyService.Get<IFirebaseAuthService>();
    if (_firebaseService.IsUserSigned()) {
        return NavigateToAsync<MainViewModel>();
    } else {
        return NavigateToAsync<LoginViewModel>();
    }
}

The pattern is consistent throughout: dependency injection → call the service method.

User registration is left as an exercise — it’s already implemented in the GitHub repository if you want to check it.

Download the current project state: https://github.com/jamontes79/xamarin-forms-firebase-sample/tree/e5eb4e032be2a24d550e8bf5635f4e8a285a5fe7

See you in Part 2 where we implement the same for iOS.


More in Desarrollo