Integrating Clerk authentication into your Flutter app

May refer for intro


Clerk authentication Flutter Video Tutorial

Complete video tutorial link explaining each step.

Code

main.dart

Designing the screen to accept user name and password

return Scaffold(
        appBar: AppBar(title: const Text("Clerk Login")),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                controller: _emailController,
                decoration: InputDecoration(labelText: 'Email'),
                keyboardType: TextInputType.emailAddress,
              ),
              TextField(
                controller: _passwordController,
                decoration: InputDecoration(labelText: 'Password'),
                obscureText: true,
              ),
              const SizedBox(height: 20),
              ElevatedButton(onPressed: _signUp, child: Text("Sign In")),
            ],
          ),
        ),
    );

if user login is successful then proceed to next step that is

if(_user!=null){
      return Scaffold(
        appBar: AppBar(title: const Text("Welcome"),),
        body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text("Name: ${_user!.username}"),
                Text("Email: ${_user!.email}"),
                ElevatedButton(onPressed: _auth.signOut, child: Text("Sign Out"))
              ],
            )
        )
      );
    }

Full Code

import 'dart:async';

import 'package:clerk_auth/clerk_auth.dart' as clerk;
import 'package:clerk_flutter/clerk_flutter.dart';
import 'package:flutter/material.dart';

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

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

  @override
  State<CustomSignIn> createState() => _CustomSignInState();
}

class _CustomSignInState extends State<CustomSignIn> {
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();

  late final ClerkAuthState _auth;
  clerk.User? _user;
  bool _loading = false;
  late final StreamSubscription _errorSub;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((_){
      if(!mounted) return;
      _auth = ClerkAuth.of(context);
      _user = _auth.user;
      _auth.addListener(_updateUser);

      _errorSub = _auth.errorStream.listen((err){
        if(mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text(err.message))
          );
        }
      });
    });
  }

  void _updateUser() {
    if(!mounted) return;
    setState(() {
      _user = _auth.user;
    });
  }

  Future<void> _signIn() async {
    setState(() {
      _loading = true;
    });

    try {
      await _auth.attemptSignIn(
        strategy: clerk.Strategy.password,
        identifier: _emailController.text,
        password: _passwordController.text,
      );
    } finally {
      if (mounted) {
        setState(() {
          _loading = false;
        });
      }
    }
  }

  Future<void> _signUp() async {
    setState(() {
      _loading = true;
    });

    try {
      await _auth.attemptSignUp(
        strategy: clerk.Strategy.emailCode,
        username: "Abhi",
        emailAddress: _emailController.text,
        password: _passwordController.text,
        passwordConfirmation: _passwordController.text
      );
    } finally {
      if (mounted) {
        setState(() {
          _loading = false;
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {

    if(_user!=null){
      return Scaffold(
        appBar: AppBar(title: const Text("Welcome"),),
        body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Text("Name: ${_user!.username}"),
                Text("Email: ${_user!.email}"),
                ElevatedButton(onPressed: _auth.signOut, child: Text("Sign Out"))
              ],
            )
        )
      );
    }

    return Scaffold(
        appBar: AppBar(title: const Text("Clerk Login")),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                controller: _emailController,
                decoration: InputDecoration(labelText: 'Email'),
                keyboardType: TextInputType.emailAddress,
              ),
              TextField(
                controller: _passwordController,
                decoration: InputDecoration(labelText: 'Password'),
                obscureText: true,
              ),
              const SizedBox(height: 20),
              ElevatedButton(onPressed: _signUp, child: Text("Sign In")),
            ],
          ),
        ),
    );
  }

  @override
  void dispose() {
    _emailController.dispose();
    _passwordController.dispose();
    if(mounted){
      _auth.removeListener(_updateUser);
    }
    _errorSub.cancel();
    super.dispose();
  }
}

Leave a Comment