Firebase Firestore Error: The operator '[]' isn't defined for the class 'Object'

Viewed 4044

im learning how to connect flutter app to firebase from this video

https://youtu.be/ggYTQn4WVuw

For me everything is exactly the same, but in Android Studio there is an error.

error: The operator '[]' isn't defined for the type 'Object'. (undefined_operator at [firebase_test] lib\services\database.dart:24)

Code where is error:

List<Brew> _brewListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map((doc) {
  return Brew(
    name: doc.data()['name'] ?? '',
    strength: doc.data()['strength'] ?? 0,
    sugars: doc.data()['sugars'] ?? '0',
  );
}).toList();}

Brew Class:

class Brew {
  final String name;
  final String sugars;
  final int strength;

  Brew({ this.name, this.sugars, this.strength });
}

Can someone help me fix this? Is this a problem with Android Studio?

4 Answers

You are using the latest Firestore dependency, version 2.0.0, which was released May 4th, 2021 days ago. There are breaking changes, read about them here.

"Add withConverter", From the documentation:

Add withConverter function to CollectionReference, DocumentReference and Query (#6015). This new method allows interacting with collections/documents in a type-safe way:

final modelsRef = FirebaseFirestore
     .instance
     .collection('models')
     .withConverter<Model>(
       fromFirestore: (snapshot, _) => Model.fromJson(snapshot.data()!),
       toFirestore: (model, _) => model.toJson(),
     );

 Future<void> main() async {
   // Writes now take a Model as parameter instead of a Map
   await modelsRef.add(Model());
   final Model model = await modelsRef.doc('123').get().then((s) => s.data());
 }

Or, you can use simply:

String name = snapshot.data.get('name');
//instead of 
String name = (snapshot.data.data() as Map<String,dynamic>)['name']

And if you want the entire map:

Map<String,dynamic> data = snapshot.data.data() as Map<String,dynamic>);
String name = data['name'] ?? '';

Use this:

doc.get('name') ?? '', 

Instead of:

doc.data()['name'] ?? '',

First solution:

Your Brew Class:

class Brew {
  final String name;
  final String sugars;
  final int strength;

  Brew({ this.name, this.sugars, this.strength });
  
  Brew.fromJson(Map<String, dynamic> json)
      : this(
          name: json['name'] as String,
          sugars: json['sugars'] as String,
          strength: json['strength'] as int,
        );

  Map<String, Object?> toJson() {
    return {
      'name': name,
      'sugars': sugars,
      'strength': strength,
    };
  }
}

Your service:

List<Brew> _brewListCollectionReference (CollectionReference<Map<String, dynamic>> collectionReference) {
  QuerySnapshot<Object?> snapshot = await collectionReference.withConverter<Brew>(
          fromFirestore: (snapshots, _ ) => Recipe.fromJson(snapshots.data()!),
          toFirestore: (brew, _ ) => brew.toJson(),
        ).get();
  return snapshot.docs.map((doc) => doc.data() as Brew).toList();
}

Note: Your "collectionReference" is the reference from your firebase collection.

For example: firestore.collection('brewCollection')

Second solution:

List<Brew> _brewListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map((doc) {
  return Brew(
    name: doc['name'] ?? '',
    strength: doc['strength'] ?? 0,
    sugars: doc['sugars'] ?? '0',
  );
}).toList();}

Third solution:

List<Brew> _brewListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map((doc) {
  return Brew(
    name: doc.get('name') ?? '',
    strength: doc.get('strength') ?? 0,
    sugars: doc.get('sugars') ?? '0',
  );
}).toList();}
Related