如何在 Flutter 中处理此类问题?

How do I handle this type issue in Flutter?

我正在学习一个在 flutter 中创建消息传递应用程序的教程系列。它有点过时了,但我正在尝试使用最新版本。

我收到以下错误:

The argument type 'Object?' can't be assigned to the parameter type 'String'.

对于此代码片段:(tryParse 之后的所有内容都带有红色下划线)。

      return chatsWithLatestMessage.map<Chat>((row) {
        final int? unread = int.tryParse(chatsWithUnreadMessages.firstWhere(
          (ele) => row['chat_id'] == ele['chat_id'],
        orElse: () => {'unread': 0})['unread']);

我尝试在末尾添加 .toString(),但后来出现更多错误,因为它应该是 int:

Use a non-nullable type for a final variable initialized with a non-nullable value.dartunnecessary_nullable_for_final_variable_declarations
A value of type 'String' can't be assigned to a variable of type 'int?'.
Try changing the type of the variable, or casting the right-hand type to 'int?'.dartinvalid_assignment
The argument type 'Object?' can't be assigned to the parameter type 'String'.

我还尝试在代码的其他几个地方添加 .toString(),但随后出现错误,指出 .toString() 之后的内容无法与字符串一起使用。

我认为所有类型都在这里发生了更多事情。有什么想法我能做什么?我是一个完全的初学者,所以很有可能,修复是我没有看到的非常基本的东西。我可以根据要求进行编辑以包含更多代码和文件。

这是代码片段所在的整个函数:

  @override
  Future<List<Chat>> findAllChats() {
    return _db.transaction((txn) async {
      final chatsWithLatestMessage = await txn.rawQuery(''' SELECT messages.* FROM 
      (SELECT
        chat_id, MAX(created_at) AS created_at
        FROM messages
        GROUP BY chat_id
      ) AS latest_messages
      INNER JOIN messages
      ON messages.chat_id = latest_messages.chat_id
      AND messages.created_at = latest_messages.created_at
      ''');

      final chatsWithUnreadMessages = 
          await txn.rawQuery('''SELECT chat_id, count(*) as unread
      FROM messages
      WHERE receipt = ? 
      GROUP BY chat_id
      ''', ['delivered']);

      return chatsWithLatestMessage.map<Chat>((row) {
        final int? unread = int.tryParse(chatsWithUnreadMessages.firstWhere(
          (ele) => row['chat_id'] == ele['chat_id'],
        orElse: () => {'unread': 0})['unread']).toString();

        final chat = Chat.fromMap(row);
        chat.unread = unread!;
        chat.mostRecent = LocalMessage.fromMap(row);
        return chat;
      }).toList();
    });
  }

编辑:这里是聊天模型:

import 'package:rethink_chat/models/local_message.dart';

class Chat {
  late String id; // added late
  int unread = 0;
  List<LocalMessage>? messages = [];
  LocalMessage? mostRecent; // added late

  Chat(this.id, {this.messages, this.mostRecent});

  toMap() => {'id': id};
  factory Chat.fromMap(Map<String, dynamic> json) => Chat(json['id']);
}

第一个错误是您声明值 final int? unread... 并将其分配给永远不会是 null 的值,并且它永远不会为空,因为您使用的是 orElse部分,
要解决此问题,您可以执行以下操作之一:
1- 将您的 unread 值声明为 final int unread
2- 或删除 orElse 部分并将 chat.unread 设置为 chat.unread = unread ?? 0;

第二个错误是,您已将 unread 值声明为 int?,但您通过将 orElse: () => {'unread': 0})['unread']).toString() 写入 .toString() 来将其分配给字符串值] 对于上述任何一种解决方案,都必须将其删除

----更新:

  final chatsWithUnreadMessages = 
      await txn.rawQuery('''SELECT chat_id, count(*) as unread
  FROM messages
  WHERE receipt = ? 
  GROUP BY chat_id
  ''', ['delivered']);

上面的代码会return给你一个List>, 例如:

chatsWithUnreadMessages = [
    {
        "chat_id": 1,
        "unread": 3
    },
    {
        "chat_id": 1,
        "unread": 3
    }
]

并且在映射它们之后,firstWhere 将为您 return 列表的整个记录​​,因此如果它找到符合 row['chat_id'] == ele['chat_id'] 的记录,它将 return整行 整行将是这样的:

{
    "chat_id": 1,
    "unread": 3
}

那是一个 Object 的 flutter 并且它不是 String 所以它不可能是 parse-able!

//Your code
return chatsWithLatestMessage.map<Chat>((row) {
  final int? unread = int.tryParse(chatsWithUnreadMessages.firstWhere(
    (ele) => row['chat_id'] == ele['chat_id'],
  orElse: () => {'unread': 0})['unread']).toString();
    ....

//Updated code
return chatsWithLatestMessage.map<Chat>((row) {
  final int? unread = int.tryParse(chatsWithUnreadMessages
      .firstWhere((ele) => row['chat_id'] == ele['chat_id'],
          orElse: () => {'unread': 0})['unread']
      .toString());
  ...
});
//What I done is I entered the ".toString()" inside the int.tryParse() parenthesis

我相信这会解决问题