Error : web_exception.WebException.new Symbol(Auth0Exception.code) : "missing_transaction"

Happy New Year. I’m building a web app using flutter and VS code, and want to implement auth0’s universal login. I’m using the latest version of Chrome for test & debug, on MacOS.

In my project I’m using the auth0_flutter/auth0_flutter_web.dart package. I am calling the initial redirect with code like this:

// Login button
ElevatedButton(
onPressed: () => {
widget.auth0
.loginWithRedirect(redirectUrl: redirectUrl)
},
child: const Text(‘LOGIN’)),

Everything is working okay up until auth0 redirects back to my app, following a successful authentication. At that point, I can see the successful issuance of a token by inspecting the Chrome Developer Tools, but my app is hitting an exception and does not successfully surface the issued token.

Some of my code is posted at this URL but I thought I would post my issue here in case this is an auth0-specific issue, and this Community is better-placed to help.

Is this a known Auth0/flutter/VS Code/Chrome issue, or am I doing something awry? Any clues much appreciated.

thanks

Robert

Hi @robertellisuk,

If you are seeing tokens in your browser then it sounds like the auth transaction is happening successfully. What line of code is throwing the error?

Thanks for coming back to me. I’ve made some modifications to my code, and initially thought I had made some progress by changing some of the args being passed to the auth0 SDK:

auth0
        .onLoad(
            audience: auth0Audience,
            useRefreshTokens: true,
            cacheLocation: CacheLocation.localStorage)
        .then((final credentials) => () {
              auth0AuthenticatedUser = credentials?.user;
            });

I believe that adding ‘useRefreshTokens’ and ‘cacheLocation’ has helped, because before they were put in place, my login scenario would not work at all. With these in place, if I start a debug session with my app already logged in (presumably with a cookie or equivalent providing persistence) then it works as expected.

However in any other scenario, for example, if I start a debug session logged out, and try to login with a redirect, then I am consistently hitting this same exception:

Paused on promise rejection - Error: missing_transaction: Invalid state

As previously mentioned, when this occurs, the error is visible in Chrome Dev, but never ‘bubbles up’ to VS code, which just behaves as if a breakpoint has been hit.

I’m a bit lost for ideas at this stage - cannot understand for the life of me why this shouldn’t work.

thanks

Robert

My latest code for my login page:

import 'package:flutter/material.dart';
import 'package:auth0_flutter/auth0_flutter_web.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:go_router/go_router.dart';

class LoginPage3 extends StatefulWidget {
  final Auth0Web auth0;

  const LoginPage3({super.key, required this.auth0});

  @override
  State<LoginPage3> createState() => LoginPage3State();
}

class LoginPage3State extends State<LoginPage3> {
  bool? isLoggedInWidgetVar;
  String redirectUrl = dotenv.env['AUTH0_LOGIN_REDIRECT_URL'].toString();
  String appBarName = dotenv.env['APP_BAR_NAME'].toString();

  late Future<bool> loggedInFuture;

  @override
  initState() {
    super.initState();

    WidgetsBinding.instance
        .addPostFrameCallback((_) => ifLoggedInThenRedirectCallback());

    loggedInFuture = loginHasValidCredentials();
  }

  Future<bool> loginHasValidCredentials() async {
    final loggedIn = await widget.auth0.hasValidCredentials();
    // if (loggedIn) {
    //   await widget.auth0.credentials();
    // }
    isLoggedInWidgetVar = loggedIn;
    return loggedIn;
  }

  void ifLoggedInThenRedirectCallback() {
    bool isLoggedIn = (isLoggedInWidgetVar ??= false);
    if (isLoggedIn) {
      context.go('/coreMenu');
    }
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<bool>(
        future: loggedInFuture,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            if (snapshot.requireData) // logged in
            {
              return const SizedBox.shrink();
            } else // not logged in
            {
              return Scaffold(
                  appBar: AppBar(
                    title: Text(appBarName),
                    backgroundColor: Colors.purple,
                    foregroundColor: Colors.white,
                  ),
                  body: Column(children: [
                    // Logo
                    const Icon(Icons.quiz),

                    // Login button
                    ElevatedButton(
                        onPressed: () => {
                              widget.auth0
                                  .loginWithRedirect(redirectUrl: redirectUrl)
                            },
                        child: const Text('LOGIN')),

                    // Sign up button
                    TextButton(
                        onPressed: () => throw Exception(), //todo
                        child: const Text('SIGN UP / CREATE ACCOUNT'))
                  ]));
            }
          } else // awaiting async login status
          {
            return const CircularProgressIndicator();
          }
        });
  }
}

From Chrome Developer Tab:

errors.dart:294 Uncaught (in promise) Error: missing_transaction: Invalid state
    at Object.throw_ [as throw] (errors.dart:294:3)
    at auth0_flutter_plugin_real.Auth0FlutterPlugin.new.initialize (auth0_flutter_plugin_real.dart:41:9)
    at initialize.throw (<anonymous>)
    at async_patch.dart:60:31
    at _RootZone.runBinary (zone.dart:1666:54)
    at _FutureListener.thenAwait.handleError (future_impl.dart:177:22)
    at handleError (future_impl.dart:858:46)
    at _Future._propagateToListeners (future_impl.dart:879:13)
    at [_completeError] (future_impl.dart:655:5)
    at async._AsyncCallbackEntry.new.callback (future_impl.dart:745:7)
    at Object._microtaskLoop (schedule_microtask.dart:40:11)
    at _startMicrotaskLoop (schedule_microtask.dart:49:5)
    at async_patch.dart:181:7

Invalid state errors are generally triggered when the original state string created by the application and passed to the auth server does not match or the callback from the request. This is often caused by two requests to authorize happening in succession and the state from request 1 is mixed up with the state from request 2.

I can’t confirm this is the case in your scenario, but you may be able to look at the chrome devtools network tab and see if there are mutliple requests getting the state crossed.

Thanks. Based on the Googling I have carried out, I agree that mismatching states seem likely to be the culprit, but It doesn’t seem that there is any obvious reason in my case why the states should be mixed. The code is very straightforward, I am only doing one authentication at a time. It also seems to me that most people who have reported struggles with this error are coming from the Auth0 Angular world, rather than the Auth0 Flutter world, which to me implies either that I am encountering a highly nuanced minor edge case issue (perhaps even one which is specific to my computer and environment), or, that relatively few developers are choosing this model of authentication for their Flutter projects.

What I have discovered is that if I use a new Icognito tab for debugging, the Invalid State exception goes away; but the Redirect still doesn’t work. When the Redirect occurs, calling auth0.hasValidCredentials() returns false. Then, I click on the LOGIN button, it is apparent that the login succeeded. So there is some kind of logical gap which requires re-rendering or refreshing, which IMHO isn’t an acceptable trade-off, even if it is likely a scenario that could be ‘hacked’ to make it work.

I have created a HAR file (based on the Incognito tab journey) but there is a lot of data in it to trawl through and I’m not sure I know what to look for.

My intention right now is to look at other options - I know Google have their own Sign in package for flutter which feels like it might be a safer bet - but if anybody has any further ideas, I do remain interested in resolving this over the longer term.

thanks

Robert

Thanks for the thorough write up. Did you have a chance to look at the network tab to see if there are two requests to /authorize?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.