简体   繁体   中英

Flutter NoSuchMethodError was thrown building FutureBuilder<DocumentSnapshot>

I am getting this error while trying to fetch user data from the cloud_firestore but it's only getting me this error when for the first time, users login to the app and navigate to the profile screen. if I hot restart or rerun the app, while in login state error goes away .

flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══
flutter: The following NoSuchMethodError was thrown building StreamBuilder<DocumentSnapshot>(dirty, state:
flutter: _StreamBuilderBaseState<DocumentSnapshot, AsyncSnapshot<DocumentSnapshot>>#f33a1):
flutter: The method '[]' was called on null.
flutter: Receiver: null
flutter: Tried calling: []("name")
flutter:
flutter: User-created ancestor of the error-causing widget was:
flutter:   SliverFillRemaining
flutter:   file:///Users/ishangavidusha/Development/MUD/mud_mobile_app/lib/screens/profile_screen.dart:102:13
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
flutter: #1      new User.from (package:mud_mobile_app/models/user_model.dart:23:22)
flutter: #2      _ProfileScreenState.build.<anonymous closure> (package:mud_mobile_app/screens/profile_screen.dart:107:38)
flutter: #3      StreamBuilder.build (package:flutter/src/widgets/async.dart:425:74)
flutter: #4      _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:125:48)
flutter: #5      StatefulElement.build (package:flutter/src/widgets/framework.dart:4047:27)
flutter: #6      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3941:15)
flutter: #7      Element.rebuild (package:flutter/src/widgets/framework.dart:3738:5)
flutter: #8      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2348:33)
flutter: #9      WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:760:20)
flutter: #10     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:280:5)
flutter: #11     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1033:15)
flutter: #12     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:975:9)
flutter: #13     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:891:5)
flutter: #17     _invoke (dart:ui/hooks.dart:249:10)
flutter: #18     _drawFrame (dart:ui/hooks.dart:207:3)
flutter: (elided 3 frames from package dart:async)

Emulator Screenshot

And this is the user model I use >

class User {
  final String id;
  final String name;
  final String profileImageUrl;
  final String email;

  User({this.id, this.name, this.profileImageUrl, this.email});

  factory User.fromDoc(DocumentSnapshot doc) {
    return User(
      id: doc.documentID,
      name: doc['name'],
      profileImageUrl: doc['profileImageUrl'],
      email: doc['email'],
    );
  }
}

FutureBuilder >

SliverFillRemaining(
  child: FutureBuilder(
    future: _getUserData(widget.userId),
    builder: (BuildContext context, AsyncSnapshot snapshot) {
      if (!snapshot.hasData) {
        return Padding(
          padding: const EdgeInsets.all(50.0),
          child: Center(
            child: CircularProgressIndicator(),
          ),
        );
      }
      User user = User.fromDoc(snapshot.data);
      return Column(
        children: <Widget>[
          Padding(...),
          Container(...),
          Container(...),
        ],
      );
    }
  )
)

And the Funtion DocumentSnapshot return >

Future<DocumentSnapshot> _getUserData(userId) async {
  return Firestore.instance.collection('users').document(userId).get();
}

"StreamBuilder dirty state" warnings are usually shown if the snapshot data doesn't have a safety check. This ensures that the snapshot contains data. However, it seems if (.snapshot.hasData) is set as a safety check on the snippet you've provided.

From the details you've given, the error seems to only occur during first user login, but the error goes away on hot restart or app restart. I suggest checking if the method _getUserData(String userId) is able to receive the userId upon the first user login where the error usually occurs. Null seems to be passed on where the error occurs based from the logs you've provided.

flutter: The method '[]' was called on null.
flutter: Receiver: null
flutter: Tried calling: []("name")
FutureBuilder<DocumentSnapshot>(
      future: users.doc(documentId).get(),
      builder:
          (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {

        if (snapshot.hasError) {
          return Text("Something went wrong");
        }

        if (snapshot.hasData && !snapshot.data!.exists) {
          return Text("Document does not exist");
        }

        if (snapshot.connectionState == ConnectionState.done) {
          Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>;
          return Text("Full Name: ${data['full_name']} ${data['last_name']}");
        }

        return Text("loading");

If you are using above similar type code and then get same error, check the firebase documentId in collection name and snapshot

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM