Q: Why does Firebase .onChildAdded.listen() block my database? Summary
In Flutter web, It seems that when I call .onChildAdded.listen() on my firebase realtime database connection, that it just stops working. If I uncomment .onChildAdded.listen() in thestate.dart , database calls work as they should. This is evidenced by the calls I make to directdb inside of DogApp.widget. I see nothing in https://firebase.google.com/docs/database/admin/retrieve-data#section-event-guarantees that would indicate this kind of behavior. Would appreciate some insight, thank you.
Github Code
https://github.com/hunterpp/testdb
You would need to create a realtimedb with an "xyz" doc
Good Output
This is print output when .onChildAdded.listen() is commented out. As you can see, COMPLETE dog 2 is shown, which means that the directdb call in DogApp.widget is getting data back from the database
test doglist
in try doglist
finally doglist
in try getItems
finally getItems
returned
COMPLETE doglist
returned getItems
COMPLETE getItems
test dog 1
in try dog 1
finally dog 1
test dog 2
in try dog 2
finally dog 2
returned
COMPLETE dog 1
returned
COMPLETE dog 2

Bad Output
When .onChildAdded.listen() is called, the dog 1 and dog 2 do not execute COMPLETE.
Here
test doglist
in try doglist
finally doglist
in try getItems
finally getItems
returned
COMPLETE doglist
returned getItems
COMPLETE getItems
test dog 1
in try dog 1
finally dog 1
test dog 2
in try dog 2
finally dog 2

main.dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  runApp(ChangeNotifierProvider(
      create: (context) => TheState(),
      child: MaterialApp(
          home: const MyHomePage(
        title: 'ok',
      ))));
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance?.addPostFrameCallback((_) {
      var state = Provider.of<TheState>(context, listen: false);
      state.dbInit();
    });
  }

  @override
  Widget build(BuildContext context) {
    // getting the size of the window
    var size = MediaQuery.of(context).size;
    var height = size.height;
    var width = size.width;
    return Scaffold(
        body: SafeArea(
            child: const SizedBox(height: 500, width: 500, child: DogList())));
  }
}

class DogList extends StatelessWidget {
  const DogList({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    directDB("doglist");
    return Consumer<TheState>(
      builder: (context, state, child) {
        var nums = state.getItems();
        if (nums == null) {
          return const Text("loading", textDirection: TextDirection.ltr);
        }
        var prod = List<int>.generate(10, (i) => i + 1);
        return CustomScrollView(
          slivers: <Widget>[
            SliverList(
              delegate: SliverChildListDelegate(
                prod
                    .map(
                      (model) => Container(
                        color: Colors.white,
                        child: DogApp(model),
                      ),
                    )
                    .toList(),
              ),
            )
          ],
        );
      },
    );
  }
}

class DogApp extends StatelessWidget {
  DogApp(this.num);
  final int num;

  @override
  Widget build(BuildContext context) {
    directDB("dog " + num.toString());
    var x = "ok " + num.toString();
    return SizedBox(
        height: 500,
        width: 500,
        child: Text(x, textDirection: TextDirection.ltr));
  }
}

thestate.dart
final DatabaseReference kDb = FirebaseDatabase.instance.ref();

class TheState extends ChangeNotifier {
  int? items;
  Query? _feedQuery;
  Future<bool> dbInit() {
    _feedQuery = kDb.child("page");
    _feedQuery!.onChildAdded.listen(_childAdded);
    initItems();
    return Future.value(true);
  }

  int? getItems() {
    return items;
  }

  void initItems() {
    var calledFrom = "getItems";
    try {
      print("in try" + " " + calledFrom);
      kDb.child('page').once().then((DatabaseEvent event) {
        print("returned" + " " + calledFrom);
        final snapshot = event.snapshot;
        if (snapshot.value != null) {
          var map = snapshot.value as Map<dynamic, dynamic>;
          items = 5;
          notifyListeners();
        }
      }).catchError((e, stackTrace) {
        print("in catchError" + " " + calledFrom);
      }).whenComplete(() => print("COMPLETE" + " " + calledFrom));
    } catch (error) {
      print("catch" + " " + calledFrom);
    } finally {
      print("finally" + " " + calledFrom);
    }
  }

  void _childAdded(DatabaseEvent event) {}
}

directdb.dart
void directDB(String calledFrom) {
  print("test" + " " + calledFrom);

  //FirebaseDatabase fd = FirebaseDatabase.instance;
  //fd.setLoggingEnabled(true);
  //DatabaseReference dr = fd.ref();
  try {
    print("in try" + " " + calledFrom);
    kDb.child('page').child("xyz").once().then((DatabaseEvent event) {
      print("returned");
      final snapshot = event.snapshot;
      if (snapshot.value != null) {
        var map = snapshot.value as Map<dynamic, dynamic>;
      }
    }).catchError((e, stackTrace) {
      print("in catchError" + " " + calledFrom);
    }).whenComplete(() => print("COMPLETE" + " " + calledFrom));
  } catch (error) {
    print("catch" + " " + calledFrom);
  } finally {
    print("finally" + " " + calledFrom);
  }
}

