supabase / supabase-flutter

Flutter integration for Supabase. This package makes it simple for developers to build secure and scalable products.
https://supabase.com/
MIT License
741 stars 183 forks source link

Flutter Supabase Auth signUp Error: _asyncStorage != null: You need to provide asyncStorage to perform pkce flow #1031

Open alexandrespindola opened 2 months ago

alexandrespindola commented 2 months ago

Title

Error during signUp with Supabase Auth in Flutter: _asyncStorage != null: You need to provide asyncStorage to perform pkce flow. The login function works correctly, the error is only when creating a new user.

Description

When attempting to create a new user using the signUp method from the supabase_flutter library in Flutter, the following error occurs:

Steps to Reproduce

Configure Supabase in Flutter as per the official documentation. Attempt to create a new user using the signUp method. Observe the mentioned error.

Expected Behavior

The signUp method should create a new user without throwing exceptions, provided all necessary parameters are supplied correctly.

Actual Behavior

The signUp method throws an exception indicating that _asyncStorage cannot be null and that asyncStorage needs to be provided to perform the PKCE flow.

Example Code

Excerpt from main.dart

import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'state/go_router_provider.dart';

final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await dotenv.load(fileName: ".env");

  await Supabase.initialize(
    url: dotenv.env['SUPABASE_URL']!,
    anonKey: dotenv.env['SUPABASE_ANON_KEY']!,
    debug: true, // optional
  );

  runApp(
    const ProviderScope(
      child: MyApp(),
    ),
  );
}

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

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final goRouter = ref.watch(goRouterProvider);

    return MaterialApp.router(
      scaffoldMessengerKey: scaffoldMessengerKey,
      routerDelegate: goRouter.routerDelegate,
      routeInformationParser: goRouter.routeInformationParser,
      routeInformationProvider: goRouter.routeInformationProvider,
    );
  }
}

image

The code below didn't work either.

[...]

const storage = FlutterSecureStorage();

  await Supabase.initialize(
    url: dotenv.env['SUPABASE_URL']!,
    anonKey: dotenv.env['SUPABASE_ANON_KEY']!,
    authOptions: FlutterAuthClientOptions(
      authFlowType: AuthFlowType.pkce,
      autoRefreshToken: true,
      pkceAsyncStorage: SecureLocalStorage(storage),
    ),
    debug: true, // optional
  );

[...]

class SecureLocalStorage extends GotrueAsyncStorage {
  final FlutterSecureStorage storage;

  SecureLocalStorage(this.storage);

  @override
  Future<String?> getItem({required String key}) async {
    return await storage.read(key: key);
  }

  @override
  Future<void> setItem({required String key, required String value}) async {
    await storage.write(key: key, value: value);
  }

  @override
  Future<void> removeItem({required String key}) async {
    await storage.delete(key: key);
  }
}
dshukertjr commented 2 months ago

@alexandrespindola You must be overriding the authOptions of the Supabase.initialize() somewhere some how. Make sure you are using the latest supabase_flutter version, and double, tripple check that you are not doing so.

If you still cannot find the cause, create a fresh new Flutter project and try it out there. If that doesn't work either, then you might have updated your pub cache or something. Try resetting it.