Flutter/Firestore - 如何 比较 2 个 文件 ?

az31mfrm  于 2022-11-17  发布在  Flutter
关注(0)|答案(4)|浏览(124)

我正在写一个语言字典使用Flutter与Firestore。我有数据库名为'西班牙语'和2个文档'容易'和'困难'。每个文档是一组对-一个关键字是原来的西班牙语单词和价值是这个单词的翻译。
我想找出哪些键(原始西班牙语单词)同时出现在'easy'和'difficult'文档中。我的查询(不起作用)是:

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;
}

为什么不工作?我做了很多显示,我从引用的代码中删除了这些显示,但是函数checkIfSelected返回**'Future'的示例**而不是bool。这是一个带有await的异步函数,所以据我所知,它不应该返回Futures。我尝试进行更改:

var myData2 = await checkIfSelected(key);

但出现错误:
await表达式只能用于异步函数中。请尝试使用“async”或“async *”标记函数体。dart(await_in_wrong_context)
但是checkIfSelected已经是async函数了。
你知道我在代码中做错了什么吗,或者可能有另一种方法来解决这个问题?

mum43rcc

mum43rcc1#

试试看这边,

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;
  }

注意事项:
异步调用不支持.forEach(),需要使用传统的循环。为什么?这个article解释得很好。我刚刚发现Dart和Node.JS几乎一样。

vxf3dgd4

vxf3dgd42#

我编写了另一种方法来获取在简单文档和困难文档中都出现的单词:

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;
  }

您可以这样调用它,它将搜索它们并返回一个包含以下西班牙语单词的列表:

List<String> OcurrencesSpanishWords = await getOccurrences();
fhg3lkii

fhg3lkii3#

如果要使用async/await,则应使用then
如果只是前者,那就是:

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;
}
oogrdqng

oogrdqng4#

这部分代码缺少async关键字。

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

相关问题