Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

After updating cloud firestore: The operator '[]' isn't defined for the type 'Object'. Try defining the operator '[]'

Every thing was working good but when i upgraded my cloud firestore dependecy. I started getting an error "The operator '[]' isn't defined for the type 'Object'. ". This error is coming in front of all the 4 userData.data()[""],

class BaseProvider with ChangeNotifier {
  //instances of firebase

  final FirebaseAuth _auth = FirebaseAuth.instance;

  final CollectionReference postsCollection =
      FirebaseFirestore.instance.collection("posts");

  final CollectionReference userCollection =
      FirebaseFirestore.instance.collection("users");

  //Creating post

  Future addPost(
    
  ) async {
    DocumentSnapshot userData =
        await userCollection.doc(_auth.currentUser.uid).get();
    return await postsCollection.doc().set({
      "id": _auth.currentUser.uid,
      "sellername": userData.data()["name"],      //Error
      "sellercontact": userData.data()["phone"],  //Error
      "sellercity": userData.data()["city"],      //Error
      "sellerstate": userData.data()["state"],    //Error
      
    });
  }
like image 428
zerochill Avatar asked May 19 '21 20:05

zerochill


2 Answers

Starting at cloud_firestore Version 2.0.0

The class DocumentSnapshot now takes a generic parameter. The declaration:

abstract class DocumentSnapshot<T extends Object?> {

and therefore it contains an abstract method of type T:

  T? data();

Therefore you need to do the following:

    DocumentSnapshot<Map<String, dynamic>> userData =
        await userCollection.doc(_auth.currentUser.uid).get();
    return await postsCollection.doc().set({
      "id": _auth.currentUser.uid,
      "sellername": userData.data()["name"],      
      "sellercontact": userData.data()["phone"],  
      "sellercity": userData.data()["city"],      
      "sellerstate": userData.data()["state"], 
      
    });

Now data() method will be of type Map<String,dynamic> and you can access the data as you normally do using the [] operator.


Another Example:

Query query = FirebaseFirestore.instance.collection("collectionPath");
final Stream<QuerySnapshot<Map<String,dynamic>>> snapshots = query.snapshots();

The above will give the error:

A value of type 'Stream<QuerySnapshot<Object?>>' can't be assigned to a variable of type 'Stream<QuerySnapshot<Map<String, dynamic>>>'.

You get this error because Query has the following declaration:

abstract class Query<T extends Object?>

while snapshots() returns the following:

Stream<QuerySnapshot<T>> snapshots({bool includeMetadataChanges = false});

Since a type wasn't specified for Query and since T extends Object?, therefore in the code snapshots() will have the following return type Stream<QuerySnapshot<Object?>> and you will get the above error. So to solve this you have to do:

Query<Map<String,dynamic>> query = FirebaseFirestore.instance.collection("collectionPath");
final Stream<QuerySnapshot<Map<String,dynamic>>> snapshots = query.snapshots();

According to the docs:

BREAKING REFACTOR: DocumentReference, CollectionReference, Query, DocumentSnapshot, CollectionSnapshot, QuerySnapshot, QueryDocumentSnapshot, Transaction.get, Transaction.set and WriteBatch.set now take an extra generic parameter. (#6015).

Therefore you need to implement the above for all those classes.

like image 133
Peter Haddad Avatar answered Oct 20 '22 23:10

Peter Haddad


in my case I simply had to change snapshot.data()['parameter'] to snapshot.get('parameter')

UserModel _userFromFirebaseSnapshot(DocumentSnapshot snapshot) {
 return snapshot != null ?
    UserModel(snapshot.id,
      name: snapshot.get('name'),
      profileImageUrl: snapshot.get('profileImageUrl'),
      email: snapshot.get('email'),
    ) : null;
 }
like image 41
Nuqo Avatar answered Oct 20 '22 23:10

Nuqo