Flutter 通过查询 Firestore 创建自定义用户模型给出“类型‘Future<dynamic>’不是‘String’类型的子类型”错误

Posted

技术标签:

【中文标题】Flutter 通过查询 Firestore 创建自定义用户模型给出“类型‘Future<dynamic>’不是‘String’类型的子类型”错误【英文标题】:Flutter creating custom user model with querying firestore gives " type 'Future<dynamic>' is not a subtype of type 'String' " error 【发布时间】:2021-04-08 19:59:32 【问题描述】:

我将用户名保存在 Firestore 中,例如用户 > 用户名 > 用户名:用户名,邮件:邮件 我正在使用电子邮件,请通过身份验证。

我想创建一个自定义用户模型来保留当前用户的用户名和邮件。我可以使用 currentUser.email 在 findCurrentUser() 函数中成功访问用户名,但是当我尝试使用 findCurrentUser 函数返回的内容创建模型时,出现错误。

这是完整的错误:

════════ 异常被提供者捕获 ══════════════════════════════════════════════════ ════════════ 引发了以下断言:引发了异常 _MapStream 被监听

StreamProvider,但没有提供catchError

例外:“未来”类型不是“字符串”类型的子类型

这是我的功能和模型:

  class CustomUser 
  final String email;
  final String username;

  CustomUser(this.email, this.username,);

  Map<String, dynamic> toJson() => 
        'email': email,
        'username': username
      ;
  


  dynamic findCurrentUser() async 
    var email = _firebaseAuth.currentUser.email;
    var user =  await FirebaseFirestore.instance
        .collection("Users")
        .where('email', isEqualTo: email).get().then((value) => value.docs.first.data()['username']);
    print('user); 
    return user; 
  

  CustomUser customUser(User user) 
    return user != null
        ? CustomUser(email: user.email, username:  findCurrentUser())
        : null;
  

  Stream<CustomUser> get user 
    return _firebaseAuth.authStateChanges().map(customUser);
   

还有我的提供者:

 StreamProvider(
        create: (context) =>
        context.read<AuthenticationService>().user,
      ),

【问题讨论】:

【参考方案1】:

你总是需要在使用它之前解析一个future,即使你在一个future上调用await并在一个方法中解析它,async方法再次返回一个future。

在这种特殊情况下,您正在调用 findCurrentUser,它会为字符串字段返回 Future,因此会出现错误。

这里有一些修复,

由于您的模型中只有用户和电子邮件,我建议使用onAuthStateChange 返回的User

如果您仍想继续使用该模型,则实际上不需要进行额外的查询,如果您只需要电子邮件和用户名,则可以直接从 firebase auth 获取。

现在最简单的方法是将用户映射到一个函数中,然后进行校准以修复您的错误。


Future<CustomUser> findCurrentUser(User user) async 
    var email = _firebaseAuth.currentUser.email;

    var user =  await FirebaseFirestore.instance
        .collection("Users")
        .where('email', isEqualTo: email)
        .get().then((value) => value.docs.first.data()['username']);
    
    return CustomUser(email: user.email, username: user); 
  


Stream<CustomUser> get user 
    return _firebaseAuth.authStateChanges().map(findCurrentUser);
   

【讨论】:

以上是关于Flutter 通过查询 Firestore 创建自定义用户模型给出“类型‘Future<dynamic>’不是‘String’类型的子类型”错误的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Firestore 在 Flutter 中搜索文本

Flutter Firestore 复合查询

用于列表构建的 Flutter 中的 Firestore 嵌套查询

使用 Flutter 的 Firestore 组集合查询

Flutter:按时间戳查询 Firestore 文档

Flutter 和 Firestore 基于位置的查询和数据结构