Getting Started

This SDK leverages Rownd’s web and native iOS and Android SDKs to provide a simple interface for Flutter developers to add Rownd to their apps.

Installation

Begin by depending on rownd_flutter_plugin and provider in your pubspec.yaml:

name: my_app
---
dependencies:
  rownd_flutter_plugin: ^1.3.2
  provider: ^6.1.2

If you don’t have one already, be sure to obtain an app key from the Rownd dashboard for use in the next step.

Platform-specific configuration

There are a couple of configuration settings that must be applied to the platform-specific code for your app in order for Rownd to work properly.

Android

  1. Set your app’s targetSdkVersion to 32 or higher in your app’s build.gradle file.

  2. Set your app’s minSdkVersion to 26 or higher in your app’s build.gradle file. Rownd currently does not support an API version lower than 26.

  3. Ensure any Android activities (like MainActivity) subclass FlutterFragmentActivity instead of FlutterActivity. If you’re using the default MainActivity generated by Flutter, you can simply change the superclass to FlutterFragmentActivity like this:

class MainActivity: FlutterFragmentActivity() {}
  1. Check and update your ProGuard config using the rules from our Android SDK.

Usage

Initialize the Rownd plugin and call rowndPlugin.configure(RowndConfig(appKey: 'YOUR_APP_KEY')); within your application wherever you do most of your app’s initialization.

Now you’re ready to use Rownd in your app. The plugin provides a RowndCubit class that can be used to manage the Rownd state.

A basic sign-in example might look like this:

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:rownd_flutter_plugin/rownd.dart';
import 'package:rownd_flutter_plugin/rownd_platform_interface.dart';
import 'package:rownd_flutter_plugin/state/global_state.dart';

void main() {
  runApp(const MyApp());
}

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

  
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final rowndPlugin = RowndPlugin(); // Initialize the Rownd plugin

  
  void initState() {
    super.initState();
    rowndPlugin.configure(RowndConfig(appKey: 'YOUR_APP_KEY'));// Configure the Rownd plugin with your app key
  }

  
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => RowndCubit(rowndPlugin), // Create a RowndCubit with the Rownd plugin
      child: MaterialApp(
        title: 'Example App',
        theme: ThemeData(
          useMaterial3: true,
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
        ),
        home: BlocBuilder<RowndCubit, AuthState>(
          builder: (context, state) {
            // Use the RowndCubit to build the UI based on the current authentication state
            if (state == AuthState.authenticated) {
              return const MyHomePage();
            } else {
              return const LoginPage();
            }
          },
        ),
        routes: {
          '/home': (context) => const MyHomePage(),
        },
      ),
    );
  }
}

In this example, the home for the BlocProvider is determined by the RowndCubit’s authentication state. If the user is authenticated, the MyHomePage widget is displayed. If the user is not authenticated, the LoginPage widget is displayed.

There are many ways to define the UI based on the authentication state, but this is a simple and effective approach.

To learn more about Bloc and Cubit, see the flutter_bloc documentation.

RowndCubit

The RowndCubit class is a Cubit that manages the Rownd state. It provides a simple interface for checking the current user’s authentication status, signing in and out, and getting the current user’s profile.

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

  
  Widget build(BuildContext context) {
    var authCubit = context.watch<RowndCubit>(); // Get the RowndCubit from the context

    return Scaffold(
      appBar: AppBar(
        title: const Text('My example app'),
      ),
      body: Column(children: [
        const Center(child: Text('Welcome to my example app!')),
        ElevatedButton(
            onPressed: () async {
              authCubit.signIn(); // Sign the user in
            },
            child: const Text('Sign in')),
      ]),
    );
  }
}

API

signIn(RowndSignInOptions? options)

Signs the user in. The options parameter is optional and can be used to specify additional options for the sign-in process.

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

  
  Widget build(BuildContext context) {
    var authCubit = context.watch<RowndCubit>();

    return Scaffold(
      body: Column([
        const Center(child: Text('Welcome to my example app!')),
        ElevatedButton(
            onPressed: () async {
            authCubit.signIn(); // Sign the user in
            },
            child: const Text('Sign in')),
      ]),
    );
  }
}

RowndSignInOptions

PropertyTypeDescription
postSignInRedirect (not recommended)StringIf you’ve followed the steps to enable Android App Links, the redirect will be handled automatically. When the user completes the authentication challenge via email or SMS, they’ll be redirected to the URL set for postSignInRedirect. If this is an Android App Link, it will redirect the user back to your app.
intentStringThis option applies only when you have opted to split the sign-up/sign-in flow via the Rownd dashboard. Valid values are .SignIn or .SignUp. If you don’t set this value, the user will be presented with the unified sign-in/sign-up flow. Please reach out to support@rownd.io to enable.

signOut()

Signs the user out.

var authCubit = context.watch<RowndCubit>();
...
ElevatedButton(
  onPressed: () async {
    authCubit.signOut(); // Sign the user out
    Navigator.pushReplacementNamed(context, '/');
  },
  child: const Text("Sign out"),
)

isAuthenticated()

Returns a boolean indicating whether the user is authenticated.

var authCubit = context.watch<RowndCubit>();

bool isAuthenticated = authCubit.isAuthenticated(); // Check if the user is authenticated

manageAccount()

Displays the current user’s profile information, allowing them to update it.

var authCubit = context.watch<RowndCubit>();
...
ElevatedButton(
  onPressed: () {
    authCubit.manageAccount(); // Display the user's profile information
  },
  child: const Text("Manage Account"),
),

registerPasskey()

Registers a passkey for the user. A user must have successfully authenticated at least once before they can register a passkey.

var authCubit = context.watch<RowndCubit>();
...
ElevatedButton(
  onPressed: () {
    authCubit.registerPasskey(); // Register a passkey for the user
  },
  child: const Text("Register Passkey"),
),

user

Returns the current user’s profile as a Map<String, dynamic>.

var authCubit = context.watch<RowndCubit>();

Map<String, dynamic> user = authCubit.user; // Get the user's profile