Announcing stable FlutterFire Auth for Desktop
Tags: flutter, firebase, opensource
Published: 2022-05-12 16:27:05

# Overview

If you're just coming from this year's IO Flutter keynotes, the Flutter team has announced that Flutter on desktop platforms moved to the stable channel, which includes Linux and MacOS. Windows was announced a couple of months back. Therefore, Flutter developers now have the full power to create great experiences for desktop users, regardless of the operating system! 

With that comes an important question: how much of the Flutter ecosystem is ready for Desktop? We can't tell yet, but we have great news for you. [FlutterFire on Desktop](https://github.com/invertase/flutterfire_desktop) is making its first big step, and as of today we're excited to announce that our sponsored package **[FlutterFire Auth](https://pub.dev/packages/firebase_auth_desktop) on Linux and Windows is moving to stable** 🎉

In a previous blog where [we announced preview](https://invertase.io/blog/announcing-flutterfire-desktop), we explained the approach followed in developing the packages and the reasoning behind it, so if you're curious, give it a read.

With Firebase Auth on Linux and Windows, In addition to all user-specifc operations, you get support for the following authentication methods:

1. Email and password
2. Anonymous (guests)
3. Phone number
4. OAuth providers including: Google, Facebook, Twitter, and GitHub

# Get started on Linux and Windows

If you're already using Firebase Auth in your Flutter app, you don't need to do much. We built the packages as a platform implementation above the same API of FlutterFire. This means nothing will change for developers, it's already the same API thanks to Flutter's federated plugin system.

In the root of your Flutter project, run the following command:

```bash
flutter pub add firebase_core_desktop 
flutter pub add firebase_auth_desktop
```

This will install and add the package into your `pubspec.yaml`. 

If you're not already using `firebase_auth` in your app, you need to add it:

```bash
flutter pub add firebase_core
flutter pub add firebase_auth
```

That's it! Inside your code, you can import it this way: 

```bash
import 'package:firebase_auth/firebase_auth.dart';
```

You can see that we're not importing it as `package:firebase_auth_desktop/firebase_auth_desktop.dart`, that's because `firebase_auth_desktop` is not a standalone package, it's just a delegate implementation that will be used when you compile your app on Windows or Linux.

## Firebase configurations

If you go to the Firebase console and try to setup an app, you won't find a Linux/Windows option. The configurations you will use with `firebase_core_desktop` are web configurations. 

You can manually create a new web app in the console, copy the configurations and paste them into your app. You will need to do a couple of if-statements to return the correct configurations for each platform your app supports.

There's another option to save you some time and effort. The [FlutterFire CLI](https://github.com/invertase/flutterfire_cli) latest update **v0.2.2** added support for Linux and Windows, where the configurations will be generated and added automatically for you if it finds `firebase_core_desktop` in your `pubspec.yaml` file. Let's see an example!

First, make sure you update to the latest version of FlutterFire CLI:

```bash
dart pub global activate flutterfire_cli
```

In the root of your project, run:

```dart
flutterfire configure
```

It will ask you for the platforms which you want to configure Firebase for.

```bash
? Which platforms should your configuration support (use arrow keys & space to select)? › 
✔ android
✔ ios
✔ macos
✔ web
✔ windows
✔ linux
```

Choose your platforms, then hit enter. A new file named `firebase_options.dart` will be generated under `lib/` folder.

Taking a look inside `firebase_options.dart`:

```bash
class DefaultFirebaseOptions {	
	static FirebaseOptions get currentPlatform {
	  if (kIsWeb) {
	    return web;
	  }
	  switch (defaultTargetPlatform) {
	    case TargetPlatform.web:
	      return web;
	    case TargetPlatform.android:
	      return android;
	    case TargetPlatform.iOS:
	      return ios;
	    case TargetPlatform.macOS:
	      return macos;
	    case TargetPlatform.windows:
	      return windows;
	    case TargetPlatform.linux:
	      return linux;
	    default:
	      throw UnsupportedError(
	        'DefaultFirebaseOptions are not supported for this platform.',
	      );
	  }
	}
	...
}
```
The last step is to initialize Firebase using the generated options.
```dart
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
```
# OAuth authentication
Authenticating users with third-party providers on Firebase is a 2-steps process: 
1. First, you use a third-party package or the REST API of some provider to get the required credentials (usually access token). 
2. Next, you will call signInWithCredentials in the Firebase SDK and pass in the credentials you just got from the provider. 

Let's take Google sign-in as an example, we first need to get an `accessToken` and `idToken` from Google's API, which should happen in a browser or WebView, then we use the credentials to sign the user in using Firebase. Therefore, your user is authenticated on Firebase with Google as an authentication provider.

During the development of FlutterFire Desktop, we faced a limitation. All the third-party packages providing OAuth authentication for famous providers (such as Googe, Apple, Facebook ... etc) only supports iOS and Android, some have web. 

As a solution, we released [`desktop_webview_auth`](https://pub.dev/packages/desktop_webview_auth), which makes use of the native WebView on Linux, Windows and MacOS to authenticate users using Google, Facebook, Twitter and GitHub.

## Let's see an example

First, add the required packages:
```bash
flutter pub add firebase_core firebase_auth
flutter pub add firebase_core_desktop firebase_auth_desktop
flutter pub add desktop_webview_auth
```
Next, let the user sign in using their preferred social provider using `desktop_webview_auth` plugin.
```dart
import 'package:desktop_webview_auth/desktop_webview_auth.dart';
import 'package:desktop_webview_auth/github.dart';
final result = await DesktopWebviewAuth.signIn(
  GitHubSignInArgs(
    clientId: _githubClientId,
    clientSecret: _githubClientSecret,
    redirectUri: _redirectUri,
  ),
);
  
String? accessToken = result?.accessToken;
```
The user will see a window popping up to authenticate them with GitHub.
![desktop_webview_auth_github.gif](https://invertase-git-flutterfire-desktop-stable-invertase.vercel.app/desktop_webview_auth_github.gif)
There are 2 possible scenarios here:
1. The user closes the window without signing in, the will cancel the operation and you will get a null result.
2. The user sign in successfully, and we get a `accessToken` back, in which case you will go to the next step: authenticating with Firebase.
```dart
if (accessToken != null) {
  // Create a new Google credential.
  final credential = GithubAuthProvider.credential(accessToken);
  // Once signed in, return the UserCredential.
  await FirebaseAuth.instance.signInWithCredential(credential);
} else {
  return;
}
```
You can view the [full working example on our samples repository.](https://github.com/invertase/samples/tree/main/flutter_samples/flutter_oauth_signin)
# What's next for Desktop
Firebase Auth is only the beginning, we have [an issue tracking the progress](https://github.com/invertase/flutterfire_desktop/issues/52), we would love to hear your feedback and thoughts!