0

I am handling state management in my Flutter app using Firebase authStateChanges and the problem I am facing is authStateChanges immediately listen and changes route while it is not waiting for my rest api to finish that save user data in database

Stream<User?> get authStateChange => _account.authStateChanges();

and doing it in main.dart

import 'package:firebase_app_check/firebase_app_check.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:routemaster/routemaster.dart';
import 'package:stack_trace/stack_trace.dart' as stack_trace;
import 'package:discountlovendor/error_page.dart';
import 'package:discountlovendor/features/auth/controllers/auth_controllers.dart';
import 'package:discountlovendor/features/auth/views/splash_view.dart';
import 'package:discountlovendor/router.dart';
import 'package:discountlovendor/theme/app_theme.dart';
import 'core/language_provider.dart';

// Error getting App Check token; using placeholder token instead. Error: com.google.firebase.FirebaseException: Error returned from API. code: 403 body: App attestation failed.
// Error getting App Check token; using placeholder token instead. Error: com.google.firebase.FirebaseException: Too many attempts.
// SMS verification code request failed: unknown status code: 18002 Invalid PlayIntegrity token; app not Recognized by Play Store.
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then(
    (_) async {
      await Firebase.initializeApp();
      await FirebaseAppCheck.instance
          .activate(androidProvider: AndroidProvider.playIntegrity);

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

  FlutterError.demangleStackTrace = (StackTrace stack) {
    if (stack is stack_trace.Trace) return stack.vmTrace;
    if (stack is stack_trace.Chain) return stack.toTrace().vmTrace;
    return stack;
  };
}

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

  @override
  ConsumerState<MyApp> createState() => _MyAppState();
}

class _MyAppState extends ConsumerState<MyApp> {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ref.watch(authStateChangeProvider).when(
          data: (data) => MaterialApp.router(
            debugShowCheckedModeBanner: false,
            title: 'DiscountLO Admin',
            theme: AppTheme.theme,
            locale: ref.watch(languageNotifierProvider),
            localizationsDelegates: const {
              AppLocalizations.delegate,
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate
            },
            supportedLocales: const [Locale("en"), Locale("hi")],
            routeInformationParser: const RoutemasterParser(),
            routerDelegate: RoutemasterDelegate(
              routesBuilder: (context) {
                debugPrint("get $data");
                if (data != null) {
                  debugPrint("cnsakcnalma");
                  return loggedInRoute;
                }
                return loggedOutRoute;
              },
            ),
          ),
          error: (error, stackTrace) => ErrorPage(text: error.toString()),
          loading: () => const SplashScreen(),
        );
  }
}

while the problem I am facing is when auth State changes it quickly listen and changes route while it is not waiting for my rest api to complete and save user data

  void verifyOTp(
      {required String verificationID,
      required String otp,
      required VoidCallback onComplete,
      required VoidCallback onFailed,
      required VoidCallback onDone,
      required BuildContext context,
      VendorModal? vendorModal,
      File? shopPicture,
      File? documentPicture,
      required bool isLogin}) async {
    final res = await _authAPI.verifyOTp(verificationID, isLogin, otp,
        (String userid) async {
      onComplete.call();
      await getVendor(
        context: context,
        onComplete: onDone,
        userid: userid,
        onGetttingData: (vendorData) {
          _ref.read(userProvider.notifier).update((state) => vendorData);
        },
      );
    }, () async {
      onComplete.call();
      await createNewVendor(
        onDone: onDone,
        context: context,
        vendorModal: vendorModal!,
        shopPicture: shopPicture!,
        documentPicture: documentPicture!,
      );
    }, onFailed, context);
    res.fold(
      (l) => showSnackBar(context, l.message),
      (r) {},
    );
  }

please help

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
abhi jain
  • 41
  • 1
  • 5

1 Answers1

0

I'm not sure but i believe you can use "Future" widget which will listen to server and when it's over it will then change routes for more information on future and how to use please check: What is a Future and how do I use it?