Flutter CTO Report 2024
Get insights about Flutter directly from CTOs, CIOs, Tech Leads, and Engineering Managers!

Building 6-Platform Flutter App: Using 3 Auth Providers & Supabase

Jan Arlukiewicz
Flutter Developer at LeanCode
Mar 28th, 2024 • 10 min.
Free product design tips
Join our Newsletter for Expert Flutter Tips & Product Design Insights from our seasoned team!
By submitting your email you agree to receive the content requested and to LeanCode's Privacy Policy.
or follow us

We've created a cross-platform Flutter application that effortlessly integrates sign-in options through Google, Apple, and Magic Link authentication. As a result, users can access their favorite features from any device, knowing that the sign-in process remains consistent across all platforms. 

In this article, you will discover why Supabase became our choice and how we used Supabase Auth to enable sign-in via three major providers. We will also describe the obstacles we faced along the way. Intrigued? Keep reading.

Introduction - a project background

One of the common business requirements when starting a new app development is implementing social and email sign-in. Finding a reliable authentication provider, especially in the ever-evolving app development landscape, is quite difficult. If you want to learn what lies beneath the whole concept, check out our article about Identity Management

Several Identity Management Solutions are available on the market. One of the common choices is Firebase Authentication by Google, which is well known for being quite easy to implement Google sign-in due to the shared Google ecosystem. However, there is one noteworthy contender in the Flutter authentication arena that deserves attention.

Supabase advertises itself as “an open-source alternative to Firebase.” It not only offers a wide array of third-party authentication methods but also officially provides Dart and Flutter packages in the pub.dev package repository, which significantly accelerates Flutter app development.

At LeanCode, we started a demanding Flutter project that required the creation of a single Flutter app for a remarkable number of six platforms (including three desktop platforms):

  • Android,
  • iOS,
  • Web,
  • Windows,
  • MacOS,
  • Linux.

One business requirement was to enable users to log in the same way on each of the 6 platforms. This project was implemented by a team consisting entirely of mobile application developers, and the requirement for a cross-platform application pushed us to seek a reliable SaaS authentication provider.

Now, let's dive into Supabase features.

Handful features of Supabase

Supabase Auth, also known as open source Firebase alternative, caught the attention of our development team first and foremost because it supports all three integrations: Apple auth, Google auth, and Magic Link sign-in. Apart from authentication, Supabase offers other useful tools that allow adding advanced functionalities to the app.

The first and most significant one is the SQL database accessible from the mobile platform, with row-level security included for every project. From a web browser, developers can access a table editor, easily view data by writing SQL queries, and control which users are permitted to perform operations on rows within tables and views. Since the database and authentication come from a single provider, it simplifies integration and eases implementation. This fact made Supabase a strong candidate when choosing an auth provider in our projects’ initial phase.

Supabase also offers real-time messages out of the box, enabling devices to listen to Postgres database changes and send messages to authorized clients. This is a good foundation for implementing instant data synchronization across user devices, which we facilitated in the later phase of the project.

The next helpful feature from Supabase is Edge Functions. These are server-side TypeScript functions distributed globally at the edge, near the users. Functions can be called directly from inside your Flutter app and enable complex operations on multiple tables, which typically would require admin access to the database. Functions are useful when implementing, for example, user account deletion because this operation requires removing user data from the profiles table, a user from the user registry, and all corresponding user data from tables.

Apart from the features above, Supabase provides comprehensive documentation that includes step-by-step instructions on configuring authentication for each provider, not only in Flutter but in any programming language for which Supabase provides libraries. The documentation contains Flutter examples and Dart snippets, making it easier for developers to familiarize themselves with the setup process.

Knowing Supabase advantages, let’s explore the authentication flows.

Authentication flows and implementation

It’s time to explain sign-in with Google, Apple, and a Magic Link authentication flows. In this paragraph, you will also learn what a native sign-in is and how it makes the authentication process more pleasant for users.

Starting with Google sign-in, Supabase requires the setup of a new project in the Google Cloud Platform (GCP) and obtaining OAuth 2 credentials. In the app authentication flow looks as follows:

  1. Upon clicking the "Sign-in with Google" button, the user is redirected to the default web browser, where they can select an already-added Google account or sign-in to an existing one.
  2. Behind the scenes, Supabase Auth uses the Google OAuth 2.0 APIs (which are OpenID Connect certified) to perform the authentication.
  3. After successful authentication, the browser redirects the user back to the app through a preconfigured deep link.
  4. The link contains all the parameters necessary for signing in. Then OAuth2 callback URL is easily parsed by the supabase_client Flutter package, which gets all parameters from the fragment and gets a login session.

Moving on to Apple sign-In, it also requires configuring the Apple provider credentials in the Supabase dashboard. The flow is very similar to Google sign-in:

  1. The user clicks the "Sign-in with Apple" button. This call takes the user to Apple's consent screen, where they can sign-in using AppleID.
  2. Behind the scenes, the Supabase Auth server sends a request to the Sign-in with Apple REST API to begin the flow. API returns an authorization code, which is exchanged for an access token and a refresh token.
  3. After successful authentication, the user is redirected back to the app through the same deep link as for a Google sign-in.
  4. The supabase_client library gets OAuth2 parameters from the redirect-URL fragment to sign the user in, and the login session is established.

When it comes to logging in with Apple, it’s important that users can still use their Apple ID to log in on devices outside of the Apple ecosystem by using a web browser.

The Magic Link authentication method it’s a password-less sign-in approach, where a user just submits an email address. There is no distinction between sign-in and sign-up in the app - the user fills in only one form field. After form submission, Supabase internally decides if the user should receive a “Confirm Signup” or “Sign-in with Magic Link” email. In the Supabase console, two separate Email templates can be configured, each containing the appropriate information, and the user receives an appropriate one depending on whether the account exists or not. The process is simple as follows:

  1. The user provides an email address in the app and requests an email containing a Magic Link.
  2. Supabase receives the email request and sends the appropriate email through an SMTP server.
  3. The user opens the email, clicks the Magic Link, and is redirected back to the app to the same Redirect URL as in the Google/Apple Sign-In process.
  4. Upon successfully retrieving the auth session, the user is signed into the app.

There’s also a native sign-in for Apple and Google, apart from previously mentioned flows. It allows users to log into the app by using familiar-looking dialogs similar to those on the devices they use, such as Android and iOS. Before the native sign-in introduction in August 2023, users needed to sign-in by using the default device’s web browser and type in their login and password from the beginning. Native sign-in removes this extra step in the process and keeps it entirely within the app. There is no need to open a web browser, which makes user login quicker and overall experience more friendly. Documentation describes the underlying architecture as follows:

”Behind the scenes, these native sign-in methods use ID tokens. They’re a formalised version of a JWT that is issued by Apple or Google and contain profile information. Supabase Auth now can properly validate the ID tokens and create new or link to existing user accounts based on email similarity (…) OS and Android, offer a built-in identity provider for convenient user authentication.”

Developers, on the other hand, can implement native sign-in easily by using packages sign_in_with_apple, google_sign_in, and supabase_flutter. They all contain a handful of authentication methods that can be easily used directly in Flutter code. Native is available on iOS, macOS, tvOS and watchOS apps in the Apple ecosystem and all Android variants in the Google ecosystem. What is important sign-in via a web browser remains still available outside these platforms.

Right Redirect URL per platform

Redirecting the user back to the app after sign-in is the penultimate step in the sign-in process. Making sure that the user will be properly brought back to the app on whichever platform the app runs is important, especially since specific platforms require different URLs. 

In the app, developers can specify the URL to which the app should redirect users after a successful sign-in. In the Supabase console, only one default redirect URL can be set, which will be used if no redirect URL is specified in the app. Other URLs, besides the default one, can be used in Flutter code, but they need to be whitelisted — added to the allow list in the console. 

We leveraged this flexibility and utilised the flutter/foundation package to detect the platform the app is running on. To achieve this, we've created an enum AppPlatform with a String getter signInRedirectUrl, which returns a redirect URL suited to the platform the app is running on. Within this enum we added 2 constant redirect URLs: webUrl and deeplinkUrl, returned depending on the boolean isWeb. Check the implementation on the following example:

enum AppPlatform {
String get signInRedirectUrl {
    const webUrl = 'https://${web_app_url}/login-callback/';
    const deeplinkUrl = '${deeplink_url_scheme}://login-callback/'	
    return isWeb ? webUrl : deeplinkUrl;
}

Continuing with proper URL usage, the supabase_client library contains two methods: signInWithOAuth and signInWithOtp. Both allow setting redirectTo parameter and do exactly what we need - properly redirect back to the app after successful sign-in.

class SignInCubit {
	Future<void> signInWithSocialAuth(SocialLogin social) async {
	// Sign in via Google/Apple auth provider
	SupabaseClient.auth.signInWithOAuth(
        social.provider, // Provider.google or Provider.apple
        redirectTo: AppPlatform.current.signInRedirectUrl,
        authScreenLaunchMode: LaunchMode.externalApplication,
	  );
	}
	
Future<void> signInWithOTP({required String email}){
	// Sign in using magic-link
	SupabaseClient.auth.signInWithOtp(
        email: email,
        emailRedirectTo: AppPlatform.current.signInRedirectUrl,
	  );
	}
}

Please note that for app state management, we use Cubits from the flutter_bloc package. If you want to learn how to use Bloc and Cubit, please check the readme and example in the package documentation.

💡 Important facts: When signing in via magic-link/one-time password, the user can open an email on any device. However, one Magic Link can be used only once. For example, a user can’t use the same email to first sign-in on mobile, and then sign-in on the web using the link from the same email. The web browser will first attempt to open the native app or inform the user that the app is not installed.

Using Flatpak to distribute the app on Linux - finding a way

Implementing sign-in on Linux was quite a journey. When building and distributing the Flutter app for Linux, you have many options. 

We started by exploring the following three: AppImage, Snapcraft, and Flatpak. All of them represent a way of encapsulating an app into a package whose format is respected by various Linux distributions and enables successful app installation and running.

At first, we tried an approach of building the Flutter app into an AppImage. Unfortunately, when it came to redirecting back to the app after sign-in, we encountered an obstacle in the AppImage runtime. A redirect URL after sign-in is set to:

"{scheme-URL}//login-callback/" + URL fragment. The fragment contains long strings such as access_token, provider_token, token_type, and parameters expires_at & expires_in, making it quite a long URL. 

It appeared that AppImage has an unpleasant buffer size limit of 1024 characters. Unfortunately, this limitation made it impossible to navigate back after signing in to the AppImage app. This bug, let’s say, can be fixed either by manually changing the AppImage builder and workflow or by waiting for a GitHub issue to be resolved. We did not want to change the AppImage builder manually and cared about time, so we were forced to seek an alternative solution for developing the application for Linux.

The next choice was Flatpak Builder, which eventually allowed us to distribute an app for Linux, but it also needed some tweaks. After finding the flutter_flatpak_example repo on GitHub, it became clear that building a Flutter app as a Flatpak is possible. The main changes we performed were adjusting the GitHub workflow to our project file structure and setting the app version and release date in the distributed Flatpak app. When it comes to redirecting back to the app after sign-in, the Linux app uses the same redirect URL as desktop and mobile versions of the app.

All this effort paid off, allowing us to build and distribute the Linux application successfully. Users can log in using Google, Apple, and the Magic Link.

Free product design tips
Join our Newsletter for Expert Flutter Tips & Product Design Insights from our seasoned team!
By submitting your email you agree to receive the content requested and to LeanCode's Privacy Policy.
or follow us
Find out what CTOs & Tech Leads say about Flutter
Flutter CTO Report 2024

Summary

We've successfully created a cross-platform Flutter app that supports sign-in via Google, Apple, and Magic Link authentication. Each sign-in method is supported on every one of the six platforms, increasing the convenience of using the app and making the sign-in experience similar on every device. 

Choosing the right authentication provider is crucial to shortening the app's time to market. After using Supabase Auth in the current project, we can say it was a good choice. Its extensive range of authentication providers and good Flutter packages make development more pleasant, and a user-friendly web console makes user management much easier. 

However, using Supabase is an example of how to create a new cross-platform app with an authentication feature. To learn about the Ory Kratos Identity Management Solution used in other LeanCode projects, please refer to the article series dedicated to this topic.

If you are looking for a custom software development service that includes a solution like this, you can order a free 30-minute consultation call with our experts.

Rate this article
5.00 / 5 Based on 4 reviews
Meet our expert

Let's schedule a talk!

Mateusz Wojtczak
Head of Mobile at LeanCodemateusz.wojtczak@leancode.pl
Mateusz Wojtczak, Head of Mobile at LeanCode

Articles you may like

Implementing Social Media Activity Feed with Stream

In a recent project, we embarked on the exciting task of enhancing an existing app with dynamic social media elements. Choosing Stream as our ally, we navigated through challenges and came up with strategies that helped us overcome them, resulting in the successful delivery of a news feed feature. Read our complex article.
Social Media Activity Feed with Stream

Identity Management Solutions, Part I: Introduction

With the changing landscape of identity management, at LeanCode we faced the challenge of selecting a new identity management solution that would be our default for the coming years. We want to share with you the whole journey. Find out more about our approach to this task.
Choosing Indentity and Access Management solution

Flutter Conferences 2024: Must-Attend Events for Flutter Devs!

At LeanCode, we love live events. As co-founders of Flutter Europe and founder of Flutter Warsaw, we take every opportunity to visit our friends at other events of this kind. This time, we're diving into the most exciting conferences tailored specifically for Flutter enthusiasts in 2024. As a result, you can grab this curated list of Flutter conferences.
List of Flutter Conferences 2024