Skip to main content

Flutter Quickstart

This is step 4 of the getting started sequence. By the end you will have a working Flutter app with sign-in and sign-out powered by ThunderID on both iOS and Android.

What You Will Learn
  • Create a new Flutter project
  • Install the thunderid_flutter package
  • Add working sign-in and sign-out using Flutter widgets
  • Display the signed-in user's name
Prerequisites
  • About 20 minutes
  • Steps 1–3 complete: ThunderID running, an application registered, and a sign-in flow built. Start at Get ThunderID if you haven't already.
  • Flutter 3.16+ and Dart 3.2+
  • iOS 16+ or Android API 26+ target device or simulator
Example Source Code

Check out the complete Flutter Quickstart Sample in the ThunderID repository.

1

Create a Flutter App

Create a new Flutter project:

flutter create my_app
cd my_app
note

If you already have an existing Flutter project, skip this step.

2

Install thunderid_flutter Package

Add the package to your pubspec.yaml:

pubspec.yaml
dependencies:
thunderid_flutter: ^0.1.0

Then install it:

flutter pub get
3

Configure a Callback URL Scheme

ThunderID redirects back to your app after sign-in and sign-out using a custom URL scheme. You need to register this scheme on both platforms.

iOS

Open ios/Runner/Info.plist and add a URL scheme under URL Types:

ios/Runner/Info.plist
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>dev.thunderid.app</string>
</array>
</dict>
</array>

Android

Open android/app/src/main/AndroidManifest.xml and add an intent filter inside your <activity> tag:

android/app/src/main/AndroidManifest.xml
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="dev.thunderid.app"
android:host="callback" />
</intent-filter>

Register the URIs in the console

In the ThunderID console, open the application you registered in step 2 and add the following as an Allowed Redirect URI:

dev.thunderid.app://callback

Add the same value as an Allowed Post-Logout Redirect URI:

dev.thunderid.app://logout
4

Initialize the SDK

Wrap your root widget with ThunderIDProvider in lib/main.dart:

lib/main.dart
import 'package:flutter/material.dart';
import 'package:thunderid_flutter/thunderid_flutter.dart';

void main() {
runApp(
ThunderIDProvider(
config: ThunderIDConfig(
baseUrl: 'https://localhost:8090',
clientId: '<your-client-id>',
scopes: const ['openid', 'profile', 'email'],
afterSignInUrl: 'dev.thunderid.app://callback',
afterSignOutUrl: 'dev.thunderid.app://logout',
applicationId: '<your-application-id>',
),
child: const MyApp(),
),
);
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return const MaterialApp(
home: RootScreen(),
);
}
}
Configuration

Replace <your-client-id> with the Client ID and <your-application-id> with the Application ID from your ThunderID application settings.

Configuration Parameters

ParameterDescription
baseUrlYour ThunderID instance URL. Must use HTTPS.
clientIdThe Client ID from your ThunderID application
scopesOAuth 2.0 scopes to request. Include 'openid' at minimum.
afterSignInUrlThe redirect URI to return to after sign-in
afterSignOutUrlThe redirect URI to return to after sign-out
applicationIdThe Application ID used for embedded (app-native) sign-in flows
5

Add Sign-In and Sign-Out

Create a root screen that reads auth state from ThunderIDProvider.of(context) and routes to either your auth or home screen.

Create lib/root_screen.dart:

lib/root_screen.dart
import 'package:flutter/material.dart';
import 'package:thunderid_flutter/thunderid_flutter.dart';
import 'auth_screen.dart';
import 'home_screen.dart';

class RootScreen extends StatelessWidget {
const RootScreen({super.key});

@override
Widget build(BuildContext context) {
final thunder = ThunderIDProvider.of(context);

if (!thunder.initialized || thunder.isLoading) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()),
);
}

return thunder.isSignedIn ? const HomeScreen() : const AuthScreen();
}
}

Create lib/auth_screen.dart to display the sign-in form:

lib/auth_screen.dart
import 'package:flutter/material.dart';
import 'package:thunderid_flutter/thunderid_flutter.dart';

enum _AuthMode { signIn, signUp }

class AuthScreen extends StatefulWidget {
const AuthScreen({super.key});

@override
State<AuthScreen> createState() => _AuthScreenState();
}

class _AuthScreenState extends State<AuthScreen> {
_AuthMode _mode = _AuthMode.signIn;

@override
Widget build(BuildContext context) {
final thunder = ThunderIDProvider.of(context);
final applicationId = thunder.config?.applicationId ?? '';

return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 40),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SegmentedButton<_AuthMode>(
segments: const [
ButtonSegment(value: _AuthMode.signIn, label: Text('Sign In')),
ButtonSegment(value: _AuthMode.signUp, label: Text('Create Account')),
],
selected: {_mode},
onSelectionChanged: (s) => setState(() => _mode = s.first),
),
const SizedBox(height: 28),
if (_mode == _AuthMode.signIn)
SignIn(applicationId: applicationId)
else
SignUp(applicationId: applicationId),
],
),
),
),
);
}
}
6

Display User Profile Information

Create lib/home_screen.dart to show the authenticated user's name and a sign-out button:

lib/home_screen.dart
import 'package:flutter/material.dart';
import 'package:thunderid_flutter/thunderid_flutter.dart';

class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});

@override
Widget build(BuildContext context) {
final thunder = ThunderIDProvider.of(context);
final user = thunder.user;

return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (user != null) ...[
Text(
'Welcome, ${user.displayName ?? user.email ?? 'User'}!',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
user.email ?? '',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
const SizedBox(height: 24),
],
SignOutButton(),
],
),
),
);
}
}
7

Run the App

Start an iOS simulator or connect an Android device, then run:

flutter run
Success

You should see the sign-in form. Enter the test user credentials you created in step 2 and tap Submit. After successful authentication, the home screen displays the user's name and a Sign Out button.

You're Done

You have completed the full getting started sequence:

  1. ThunderID running
  2. ✅ Application registered with a Client ID
  3. ✅ Sign-in flow built in the Flow Designer
  4. ✅ Flutter app integrated and authenticating

What's Next

ThunderID LogoThunderID Logo

Product

DocsAPIsSDKs
© WSO2 LLC. All rights reserved.Privacy PolicyCookie Policy