【问题标题】:Using model class in flutter (dart)在颤振中使用模型类(飞镖)
【发布时间】:2020-01-28 11:10:14
【问题描述】:

我正在尝试使用一些方法创建一个模型类,以简化从 Firebase 中检索信息的过程。

我有一个“未注册”页面,用户点击“使用 google 登录”按钮。如果我的用户已经注册,它会检查数据库以查看他是否完成了他的个人资料,否则它将使用字段profileCompleted: false 将基本数据写入数据库并将用户重定向到个人资料页面,以便他可以完成他的个人资料。

我正在尝试在这里使用模型,但我遇到了各种错误(刚开始学习颤振/飞镖)。

我会分享一些代码,如果还不够,请告诉我!

未注册的页面。

    if (user != null) {
      await prefs.setString('id', user.uid);
      // Check is already sign up
      final QuerySnapshot result = await Firestore.instance
          .collection('users')
          .where('id', isEqualTo: user.uid)
          .getDocuments();
      final List<DocumentSnapshot> documents = result.documents;

      if (documents.length == 0) {
        debugPrint("User not in DB ?");
        //debugPrint(userInfo.toString());
        // Update data to server if new user

        Firestore.instance.collection('users').document(user.uid).setData({
          'id': user.uid,
          'nickname': user.displayName,
          'photoUrl': user.photoUrl,
          'email': user.email,
          'createdAt': DateTime.now(),
          'provider': user.providerId,
          'profileCompleted': false,
          'bloodType': 'A',
          'rhType': 'Negativ',
          'donatedBefore': 'Nu',
          'lastDonation': '0'
        });
        Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => CompleteProfile(
                      currentUserId: user.uid,
                      userInfo: documents.single,
                    )));
      } else if (documents.single["profileCompleted"] == false) {
        Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => CompleteProfile(
                      currentUserId: user.uid,
                      userInfo: documents.single,
                    )));
      } else {
        Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => HomePage(
                      currentUserId: user.uid,
                      userInfo: documents.single,
                    )));
      }
    }

完整的个人资料页面

class CompleteProfile extends StatefulWidget {
  final String currentUserId;
  final userInfo;
  static const routeName = '/profile';
  final User user;

  CompleteProfile(
      {Key key,
      this.title,
      @required this.currentUserId,
      @required this.userInfo,
      this.user})
      : super(key: key);

  final String title;

  @override
  _CompleteProfileState createState() => _CompleteProfileState(user,
      currentUserId: this.currentUserId, userInfo: this.userInfo);
}

class _CompleteProfileState extends State<CompleteProfile> {
  User user;

  _CompleteProfileState(this.user,
      {Key key, @required this.currentUserId, @required this.userInfo});
  final String currentUserId;
  final userInfo;

我的问题是,如果我尝试设置这样的下拉菜单 ->

child: ListTile(
title: DropdownButton<String>(
items: _bloodTypes.map((String value) {
return DropdownMenuItem<String>(
value: value, child: Text(value));
}).toList(),
style: textStyle,
value: retrieveBloodType(user.bloodType),
onChanged: (value) => updateBloodType(value),

并且在默认值上->

  String retrieveBloodType(String value) {
    return _bloodType;
  }

我收到一个错误,我正在获取 null。

我的想法是用User user = new User(userInfo["id"],userInfo["email"].... 之类的东西初始化User 模型,其中userInfo 是从firebase 检索的对象。但是,这会引发另一个错误,即只能在初始化程序中访问静态成员。

我的模型非常简单,所以这里先睹为快(几行,而不是整个模型)。

class User {
  int _id;
  String _nickname;
  int get id => _id;
  String get nickname => _nickname;
  set bloodType(String newBloodType) {
    if (newBloodType.length <= 50 && newBloodType != null) {
      _bloodType = newBloodType;
    }
  }

知道如何更改 id 才能正常工作吗?我考虑使用模型的唯一原因是简化屏幕小部件(因此我可以将所有 firebase 逻辑添加到模型而不是小部件)。

【问题讨论】:

  • 查看包json_annotationjson_serializable。他们是你这里最好的朋友。
  • 这似乎对我有帮助,但是......因为我没有足够的飞镖(或类似语言)经验,我很难想象我将如何实现这些包。您是否有任何详细的教程/示例来解释它们的使用或类似的东西?谢谢!
  • @ChennaReddy 有点头疼,但我设法解决了,这些包确实是救命稻草,谢谢!

标签: flutter dart


【解决方案1】:

我会这样做

import 'package:cloud_firestore/cloud_firestore.dart';

class User {
  final String userName;
  final String email;
  final String name;
  final String phoneNumber;
  final String profilePictureUrl;
  final Timestamp creationDate;

  const User(
    this.userName,
    this.email,
    this.name,
    this.phoneNumber,
    this.profilePictureUrl,
    this.creationDate
  );

  factory User.fromDocument(DocumentSnapshot document) {
    return User(
      document['userName'],
      document['email'],
      document['name'],
      document['phoneNumber'],
      document['profilePictureUrl'],
      document['creationDate']
    );
  }

【讨论】:

    【解决方案2】:

    如果你的模型看起来像这样会更好:

    class User {
      final String userName;
      final String email;
    
    
      User({
        this.userName,
        this.email,
     
      });
    
     User.fromMap(Map map)
      : this(
         userName : map['userName'],
         email : map['email'],
       );
    
     Map<Stringm dynmic> asMap() => {
       'userName' : userName,
       'email' : email,
      }
    

    然后您可以使用此模型将数据设置为 firebase,如下所示

    Firestore.instance.collection('users').document(user.uid).setData(user.asMap)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-12
      • 2020-11-05
      • 2020-11-28
      • 2018-09-10
      • 2019-02-05
      • 2020-09-12
      • 2020-12-25
      • 2020-04-27
      相关资源
      最近更新 更多