You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Firebase解析异常:'String'不是'index'的'int'子类型

问题:Firebase Realtime Database数据解析异常:type 'String' is not a subtype of type 'int' of 'index'

尝试从Firebase Realtime Database获取数据(数据路径为2129 -> 911),能正常获取到JSON响应,但使用自定义模型类UserDataModel解析时抛出异常:

User Data Error: type 'String' is not a subtype of type 'int' of 'index'

Firebase数据结构

{
  "2129": {
    "911": {
      "TimeStamp": 1657782900738,
      "connectedStatus": "Requested",
      "imagePath": "https://www.ppp.in/placeholder.png",
      "lastMessage": "",
      "status": "Active",
      "time": "2022-07-14 12:45:00",
      "typing": false
    },
    "xxx": {
      "imagePath": "https://asd-123.jpg",
      "lastMessage": "hi",
      "typing": false,
      "connectedStatus": "Pending",
      "unreadMessageCount": 0,
      "time": "2022-07-21 16:22:58",
      "userId": 2277,
      "TimeStamp": 1658400778129,
      "status": "Unactive",
      "username": "Users Name"
    }
  }
}

自定义模型类UserDataModel代码

UserDataModel mUserIdFromJson(String str) => UserDataModel.fromJson(json.decode(str));
String mUserIdToJson(UserDataModel data) => json.encode(data.toJson());

class UserDataModel {
  UserDataModel({
      String? imagePath, 
      String? lastMessage, 
      bool? typing, 
      String? connectedStatus, 
      int? unreadMessageCount, 
      String? time, 
      int? userId, 
      int? timeStamp, 
      String? status, 
      String? username,}){
    _imagePath = imagePath;
    _lastMessage = lastMessage;
    _typing = typing;
    _connectedStatus = connectedStatus;
    _unreadMessageCount = unreadMessageCount;
    _time = time;
    _userId = userId;
    _timeStamp = timeStamp;
    _status = status;
    _username = username;
}

  UserDataModel.fromJson(dynamic json) {
    _imagePath = json['imagePath'];
    _lastMessage = json['lastMessage'];
    _typing = json['typing'];
    _connectedStatus = json['connectedStatus'];
    _unreadMessageCount = json['unreadMessageCount'];
    _time = json['time'];
    _userId = json['userId'];
    _timeStamp = json['TimeStamp'];
    _status = json['status'];
    _username = json['username'];
  }
  String? _imagePath;
  String? _lastMessage;
  bool? _typing;
  String? _connectedStatus;
  int? _unreadMessageCount;
  String? _time;
  int? _userId;
  int? _timeStamp;
  String? _status;
  String? _username;


  set imagePath(String? value) {
    _imagePath = value;
  }

  String? get imagePath => _imagePath;
  String? get lastMessage => _lastMessage;
  bool? get typing => _typing;
  String? get connectedStatus => _connectedStatus;
  int? get unreadMessageCount => _unreadMessageCount;
  String? get time => _time;
  int? get userId => _userId;
  int? get timeStamp => _timeStamp;
  String? get status => _status;
  String? get username => _username;

  Map<String, dynamic> toJson() {
    final map = <String, dynamic>{};
    map['imagePath'] = _imagePath;
    map['lastMessage'] = _lastMessage;
    map['typing'] = _typing;
    map['connectedStatus'] = _connectedStatus;
    map['unreadMessageCount'] = _unreadMessageCount;
    map['time'] = _time;
    map['userId'] = _userId;
    map['TimeStamp'] = _timeStamp;
    map['status'] = _status;
    map['username'] = _username;
    return map;
  }

  set lastMessage(String? value) {
    _lastMessage = value;
  }

  set typing(bool? value) {
    _typing = value;
  }

  set connectedStatus(String? value) {
    _connectedStatus = value;
  }

  set unreadMessageCount(int? value) {
    _unreadMessageCount = value;
  }

  set time(String? value) {
    _time = value;
  }

  set userId(int? value) {
    _userId = value;
  }

  set timeStamp(int? value) {
    _timeStamp = value;
  }

  set status(String? value) {
    _status = value;
  }

  set username(String? value) {
    _username = value;
  }
}

Flutter获取数据的代码

void getInfo(int? mOtherUserId) async {
    mUserId = await SecureStorageRepo().getUserProfileId();
    debugPrint('mUser info: $mUserId');
    debugPrint('mOtherUserId info: $mOtherUserId');

    final DatabaseReference mRef = fDatabase
        .ref(ChatDatabase.connectedUsers)
        .child('$mUserId')
        .child('$mOtherUserId');

    mRef.once().then((snapshot) {
      try {
        var userData = snapshot.snapshot.value;
        debugPrint('User Snapshot: $userData');

        var userDataObject = json.encode(userData);
        debugPrint('User Snapshot2: $userDataObject');
        
        // 以下代码无法运行
        UserDataModel result = UserDataModel.fromJson(userDataObject);
        debugPrint('Other Users result: ${result.toJson()}');
        
      } catch (e) {
        debugPrint('User Data Error: ${e.toString()}');
      }
    });
  }

问题原因与解决方法

问题根源

Firebase Realtime Database返回的snapshot.snapshot.value本身就是Map<String, dynamic>类型的对象,不需要再调用json.encode(userData)转为JSON字符串。而UserDataModel.fromJson方法接收的是动态Map对象,当传入字符串时,方法内部执行json['imagePath']会把字符串当成数组用索引访问(字符串索引只能是int类型),因此抛出类型不匹配异常。

解决步骤

直接移除多余的json.encode步骤,将原始的snapshot.value传入UserDataModel.fromJson,同时增加非空判断避免空指针异常:

修改后的getInfo方法代码:

void getInfo(int? mOtherUserId) async {
    mUserId = await SecureStorageRepo().getUserProfileId();
    debugPrint('mUser info: $mUserId');
    debugPrint('mOtherUserId info: $mOtherUserId');

    final DatabaseReference mRef = fDatabase
        .ref(ChatDatabase.connectedUsers)
        .child('$mUserId')
        .child('$mOtherUserId');

    mRef.once().then((snapshot) {
      try {
        var userData = snapshot.snapshot.value;
        debugPrint('User Snapshot: $userData');
        
        // 增加非空判断,直接传入Map对象
        if (userData != null && userData is Map<String, dynamic>) {
          UserDataModel result = UserDataModel.fromJson(userData);
          debugPrint('Other Users result: ${result.toJson()}');
        } else {
          debugPrint('User data is null or invalid format');
        }
        
      } catch (e) {
        debugPrint('User Data Error: ${e.toString()}');
      }
    });
  }

额外说明

如果需要将模型转为JSON字符串用于存储等场景,可以使用你定义的mUserIdToJson(result)方法,不要和解析流程混淆。


内容的提问来源于stack exchange,提问作者Abhishek VD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 16:27:37