How to resolve "the getter data was called on null"?

Asked

Viewed 2,178 times

0

Personal talk!

I’m trying to create a function changeLikes where my firebase document (snapshot) has its likes incremented by Firebase by clicking on ontap through the FieldValue. However, I am receiving the following message "the getter data was called on Null".

Detail, if I specify the document the function works, but I do not want to specify the document. It has a list with several. Does anyone have any idea what I might be doing wrong?

import 'package:e_ai_casimiro/models/likes_model.dart';
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'home_screen.dart';


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

class EaiCasimiro extends StatelessWidget {

@override
Widget build(BuildContext context) {
 return ScopedModel<LikesModel>(
    model: LikesModel(),
    child: MaterialApp(
      title: "E aí,  Casimiro?",
      home: HomeScreen(),
      debugShowCheckedModeBanner: false,
     )
    );
   }
  }  




import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:scoped_model/scoped_model.dart';

class LikesModel extends Model {

final DocumentSnapshot snapshot;

LikesModel({this.snapshot});

bool _liked = true;

static LikesModel of(BuildContext context) =>
  ScopedModel.of<LikesModel>(context, rebuildOnChange: true);


bool isLiked() => _liked;

void pressed(){
_liked = !_liked;
notifyListeners();
}

void  changeLikes() async{

await Firestore.instance
    .collection("lanchonetes")
    .document(snapshot.documentID)
    .updateData({'likes': FieldValue.increment(_liked ? -1 : 1)});

   }
}

class LanchonetesContact extends StatefulWidget {
final DocumentSnapshot lanchonetes;

LanchonetesContact(this.lanchonetes);

@override
_LanchonetesContactState createState() => _LanchonetesContactState();
}

class _LanchonetesContactState extends State<LanchonetesContact> {



@override
Widget build(BuildContext context) {
return Padding(
              padding: EdgeInsets.only(top: 0.0),
              child: Card(
                  elevation: 1.0,
                  child: GestureDetector(
                      child: Container(
                        height: 70.0,
                        width: 390.0,
                        color: Colors.white,
                        child: Row(
                          children: <Widget>[
                            Icon(
                              LikesModel.of(context).isLiked() ? 
                              Icons.favorite_border : Icons.favorite,
                              color: LikesModel.of(context).isLiked() ? 
                              Colors.black : Colors.red,
                              size: 50.0,
                            ),

                            StreamBuilder(
                        stream: Firestore.instance
                               .collection('lanchonetes')
                               .document(widget.lanchonetes.documentID)
                               .snapshots(),
                                builder: (context, snapshot) => Text(
                                snapshot.data.data["likes"].toString(),
                                  style: TextStyle(fontSize: 40.0),
                            ),
                          ],
                          mainAxisAlignment: MainAxisAlignment.center,
                        ),
                      ),
                      onTap: () {
                        LikesModel.of(context).pressed();
                        LikesModel.of(context).changeLikes();

                      }

                  ))
         ),

Which returns me the following information:

════════ (114) Exception caught by widgets library  
═════════════════════════════════════════════════
The getter 'data' was called on null.
Receiver: null
Tried calling: data
User-created ancestor of the error-causing widget was: 
Row    
file:///Users/ricardooscarkanitz/AndroidStudioProjects/e_ai_casimiro/lib/contacts/lanchonetes_contact.dart:79:36
════════════════════════════════════════════════════════════════════════════════════════════════════
  • Maybe your document is not returning any record to the documentId informed... Let us know when you are giving the error

  • @Matheusribeiro believe it is in the documentId same, if I type the specific document name the function works, my snapshot is not calling the Firestore, unfortunately I am beginner in flutter and do not know how to solve.

  • Edit your question and let us know a few things: Where do you make use of the method changeLikes()? Where does the FieldValue? Debug your method changeLikes() and show us what comes in snapshot?

  • @Matheusribeiro the changeLikes is used in function onTap, the FieldValueis used to increment a value in Firebase, snapshotshould access the documents of my collection lanchonetesas in my class LanchonetesContact, but I believe you’re not accessing the document for some reason.

  • I saw that you modified your question as soon as possible I create an answer for you!

1 answer

1


The problem is you’re instilling your LikesModel within your ScopedModel but is not passing the snapshot to the model, so when you try to access it will give the error that is receiving...

Below I leave a form of correction, I do not understand much of ScopedModel but then you implement what’s missing.

In your class LikesModel do:

class LikesModel extends Model {

bool _liked = true;

static LikesModel of(BuildContext context) =>
  ScopedModel.of<LikesModel>(context, rebuildOnChange: true);


bool isLiked() => _liked;

void pressed(){
  _liked = !_liked;
  notifyListeners();
}

void  changeLikes(String docummentId) async{

await Firestore.instance
    .collection("lanchonetes")
    .document(docummentId)
    .updateData({'likes': FieldValue.increment(_liked ? -1 : 1)});

   }
}

As at first you will not have access to DocumentSnapshot it is not necessary to pass it in the creation of its class.

In your view do:

class LanchonetesContact extends StatefulWidget {
final DocumentSnapshot lanchonetes;

LanchonetesContact(this.lanchonetes);

@override
_LanchonetesContactState createState() => _LanchonetesContactState();
}

class _LanchonetesContactState extends State<LanchonetesContact> {

@override
Widget build(BuildContext context) {
  return Padding(
    padding: EdgeInsets.only(top: 0.0),
      child: Card(
        elevation: 1.0,
        child: GestureDetector(
            child: Container(
              height: 70.0,
              width: 390.0,
              color: Colors.white,
              child: Row(
                children: <Widget>[
                  Icon(
                    LikesModel.of(context).isLiked() ? 
                    Icons.favorite_border : Icons.favorite,
                    color: LikesModel.of(context).isLiked() ? 
                    Colors.black : Colors.red,
                    size: 50.0,
                  ),
                  StreamBuilder(
                    stream: Firestore.instance
                      .collection('lanchonetes')
                      .document(widget.lanchonetes.documentID)
                      .snapshots(),
                      builder: (context, snapshot) => Text(
                      snapshot.data.data["likes"].toString(),
                        style: TextStyle(fontSize: 40.0),
                    )
                  )
                ],
                mainAxisAlignment: MainAxisAlignment.center,
              ),
            ),
            onTap: () {
              LikesModel.of(context).pressed();
              LikesModel.of(context).changeLikes(widget.lanchonetes.documentID);
            }
        )
      )
    );
  }
}

That way, you pass the documentID for your method that will update!

TIP

Try not to work directly with the snapshot, try abstracting in classes and working on them, use the snapshot just to start your classes, it becomes simpler to understand and work.

  • 1

    Thanks Matheus, I researched several ways but none came close. Thanks for the tip on snapshot.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.