0

Not sure I am thinking about this right. According to my knowledge the Streambuilder is supposed to log you out if the user has been deleted from the backend which is Firebase.

The steps of what I am doing as of now -

  1. loading the app
  2. Signing in to the app
  3. Loading firebase and deleting the signed in user from the backend.

I believe doing this would log me out from the app as well. Is that right?

Here is my code -

   void main() async {
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp();
    runApp(MaterialApp(
        theme: ThemeData(
          accentColor: Colors.orange,
          primarySwatch: Colors.blue,
        ),
        home: StreamBuilder(
          stream: FirebaseAuth.instance.authStateChanges(),
          builder: (context, snapshot) {
            print(FirebaseAuth.instance.authStateChanges());
          if (snapshot.connectionState == ConnectionState.active) {
            var user = snapshot.data;
            if (user == null) {
              return Welcome();
            }
            return Conversations("Logged in");
          }
        )
    ));
  }
Sumchans
  • 3,088
  • 6
  • 32
  • 59

2 Answers2

2

Firebase Authentication uses a combination of long-lived and short-lived tokens to manage login sessions, and it may take up to an hour before the short-lived token needs to be refresh and the client detects that the client is signed out.

If you waited for less time than an hour, that is probably the reason your authStateChanges() didn't fire with a new value: the token is still valid, so the client's auth state hasn't changed yet.


If you want to learn how to revoke the user's tokens, I recommend reading the documentation on that. Fair warning though: it is quite a bit more involved than simply signing in and out on the client.


If your goal is to be able to lock out users instantly, there are probably other ways to do that. For example, when using Firebase's Realtime Database or Firestore, it is quite common to keep a list of "blocked UIDs" in the database, and check against that in the security rules of your database.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
1

When logging out by using signOut(), the state got updated right away, but it might not be the case when you delete the user.

The change might take a while to be notified to the stream at the front end. You can read more on that here: Firebase user deleted but still logged in on device

Firebase Authentication tokens are valid for one hour and cached on the user's device. It is automatically refreshed by the client SDK. Deleting the account doesn't proactively reach out to all the user's devices to delete the token.

You can try on this mini sign-in app with the provided signOut() method:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.indigo,
      ),
      home: MyApp(),
    );
  }
}

class LandingPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<User>(
      stream: FirebaseAuth.instance.authStateChanges(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.active) {
          User user = snapshot.data;
          if (user == null) {
            return Welcome();
          }
          return Conversations();
        } else {
          return Scaffold(
            body: Center(
              child: CircularProgressIndicator(),
            ),
          );
        }
      },
    );
  }
}

class Welcome extends StatelessWidget {

  Future<void> _signInAnonymously() async {
    try {
      await FirebaseAuth.instance.signInAnonymously();
    } catch (e) {
      print(e);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Sign in')),
      body: Center(
        child: RaisedButton(
          child: Text('Sign in anonymously'),
          onPressed: _signInAnonymously,
        ),
      ),
    );
  }
}

class Conversations extends StatelessWidget {

  Future<void> _signOut() async {
    try {
      await FirebaseAuth.instance.signOut();
    } catch (e) {
      print(e); // TODO: show dialog with error
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
        actions: <Widget>[
          FlatButton(
            child: Text(
              'Logout',
              style: TextStyle(
                fontSize: 18.0,
                color: Colors.white,
              ),
            ),
            onPressed: _signOut,
          ),
        ],
      ),
    );
  }
}
Bach
  • 2,928
  • 1
  • 6
  • 16