Search code examples
fluttergoogle-cloud-firestorestream-builder

Screen rebuilds itself every time I try to enter some text to TextField if I use ConnectionState.waiting


I'd like to build a profile screen with real-time changes using firestore. Whenever the profile screen opens, I get this error for a very short moment:

The following _CastError was thrown building StreamBuilder<DocumentSnapshot>(dirty, dependencies: [_LocalizationsScope-[GlobalKey#f10b3], _InheritedTheme], state: _StreamBuilderBaseState<DocumentSnapshot, AsyncSnapshot<DocumentSnapshot>>#47356):
Null check operator used on a null value

The relevant error-causing widget was: 
  StreamBuilder<DocumentSnapshot> file:///C:/Users/batuh/AndroidStudioProjects/flutter_appp/lib/screens/profile.dart:40:13
When the exception was thrown, this was the stack: 
#0      _ProfileState.build.<anonymous closure> (package:flutter_appp/screens/profile.dart:107:42)
#1      StreamBuilder.build (package:flutter/src/widgets/async.dart:545:81)
#2      _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:124:48)
#3      StatefulElement.build (package:flutter/src/widgets/framework.dart:4612:27)
#4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)

But after that moment, it gets the data and works well. I know I need to use the code below to prevent that, just like to Flutter docs say.

if (snapshot.connectionState == ConnectionState.waiting) {
        return Center(
          child: CircularProgressIndicator(),
        );
      }

But whenever I use that code, every time I press on a TextField, the profile page rebuilds itself and so it doesn't allow me to enter any text. If the code above is not used, everything works well, I am able to enter some text to TextFields, and the user data is being updated. I don't know what to do. Am I using the stream builder incorrectly? What should I do?

Here's the scaffold of the stful widget in my profile.dart file:

Scaffold(
  appBar: AppBar(
    leading: IconButton(
      icon: Icon(FontAwesomeIcons.arrowLeft),
      onPressed: () => Navigator.pop(context),
    ),
    actions: [
      IconButton(
        icon: Icon(FontAwesomeIcons.cog),
        onPressed: () => Navigator.pushNamed(context, '/settings'),
      )
    ],
  ),
  body: StreamBuilder<DocumentSnapshot>(
    stream: users.doc(FirebaseAuth.instance.currentUser!.uid).snapshots(),
    builder:
        (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
      if (snapshot.hasError) {
        return Text("Something went wrong");
      }

      return Container(...);

Fixed version:

if (snapshot.hasError) {
            return Text("Something went wrong");
          } else if(snapshot.hasData || snapshot.connectionState == ConnectionState.active) {
            return Container(...);
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }

Solution

  • You can try remove the "!" on the "data" because every time you trigger that "TextField" it will instantly looking for data. "!" in null-safety means it cannot be null object or null thing. Try remove that first because I guess your Stream builder act as a Search Recommendation