Home > Enterprise >  Flutter/Firestore – how to compare 2 documents?
Flutter/Firestore – how to compare 2 documents?

Time:11-13

I am writing a language dictionary using Flutter with Firestore. I have database named ‘Spanish’ and 2 documents ‘easy’ and ‘difficult’. Each document is a set pairs - a key is original Spanish word and the value is translation of this word.

I want to find which keys (original Spanish words) appears in both ‘easy’ and ‘difficult’ documents. My query (which is not working) is:

var myResult = await FirebaseFirestore.instance
      .collection('Spanish')
      .doc('easy')
      .get()
      .then((snapshot) { 
      if (snapshot != null)    { 
          snapshot.data()?.forEach((key, value) {  
          var myData2 = **checkIfSelected**(key); 
          print(myData2) ;
       });

Future<dynamic> checkIfSelected(String key) async {  
  bool ifSelected = false;

  var myResult2 = await FirebaseFirestore.instance
      .collection('Spanish')
      .doc('difficult')
      .get()
      .then((snapshot) {   
      if (snapshot != null) {
         snapshot.data()?.forEach((k, v) {
         if (k == key) {
          ifSelected = true;
         } 
    }
  }); 

  return ifSelected;
}

Why is not working? I made a lot of displays which I removed from quoted code, but function checkIfSelected returns Instance of 'Future' instead of bool. This is async function with await, so as I understand it should not return Futures. I tried make a change:

var myData2 = await checkIfSelected(key); 

but got error:

The await expression can only be used in an async function. Try marking the function body with either 'async' or 'async*'.dart(await_in_wrong_context)

But checkIfSelected is already an async function.

Any ideas what I did wrong in my code, or maybe there is another approach to this problem?

CodePudding user response:

Try This way,

  void getData() async {
    var snapshot = await FirebaseFirestore.instance.collection('Spanish').doc('easy').get();

    var data = snapshot.data();

    for (var key in (data?.keys.toList() ?? [])) {
      var myData2 = await checkIfSelected(key);
      print(myData2);
    }
  }

  Future<bool> checkIfSelected(String key) async {
    var snapshot = await FirebaseFirestore.instance.collection('Spanish').doc('difficult').get();

    var data = snapshot.data();

    for (var k in (data?.keys.toList() ?? [])) {
      return k == key;
    }

    return false;
  }

Note:

Asynchronous calls don't work with .forEach(), you need to use traditional loops. Why? This article explains it very well. I just discovered that Dart and Node.JS are almost the same.

CodePudding user response:

I write another approach to get the words that occur in both easy and hard documents:

  Future<Map<String, dynamic>> getEasy() async {
    DocumentSnapshot myResult = await FirebaseFirestore.instance
        .collection('Spanish')
        .doc('easy')
        .get();
    return myResult.data() as Map<String, dynamic>;
  }

  Future<Map<String, dynamic>> getDifficult() async {
    DocumentSnapshot myResult = await FirebaseFirestore.instance
        .collection('Spanish')
        .doc('difficult')
        .get();
    return myResult.data() as Map<String, dynamic>;
  }

  Future<List<String>> getOccurrences() async {
    List<String> spanishWordsThatOccursOnBoth = [];
    Map<String, dynamic> easy = await getEasy();
    Map<String, dynamic> difficult= await getDifficult();

    easy.forEach((key, value) {
      if (difficult.containsKey(key)) {
        spanishWordsThatOccursOnBoth.add(key);
      }
    });

    return spanishWordsThatOccursOnBoth;
  }

you can call it like this, and it will search for them and return a list with those Spanish words:

List<String> OcurrencesSpanishWords = await getOccurrences();

CodePudding user response:

If you want to use async/await you should not use then.

With just the former, it'd be:

Future<dynamic> checkIfSelected(String key) async {  
  bool ifSelected = false;

  var snapshot = await FirebaseFirestore.instance
      .collection('Spanish')
      .doc('difficult')
      .get()

  if (snapshot != null) {
    snapshot.data()?.forEach((k, v) {
    if (k == key) {
      ifSelected = true;
    } 
  }

  return ifSelected;
}
  • Related