Flutter issue: type 'Timestamp' is not a subtype of type 'DateTime'

4,814

Solution 1

On my projects I use

birth: parsedJson['birth'].toDate()

and works well, it's another option.

Solution 2

We solved the problem.

Instead of acting on received value, we stored our [DateTime] values parsed to [String]. So we parse these parameters back to [DateTime] the same way as described above :

import 'package:cloud_firestore/cloud_firestore.dart';

class User{
  final String _name;
  final String _gender; // 'homme' or 'femme' or 'autre'
  final DateTime _birth;
  final DateTime _license;
  final double _weight;
  final int _size;
  DocumentReference ref;

  User(this._birth,this._gender,this._license,this._name,this._size,this._weight,this.ref);

  User.fromMap(Map<String, dynamic> map, {this.ref})
      : assert(map['name'] != null && map['gender'] != null && map['birth'] != null && map['weight'] != null && map['size'] != null),
        _name = map['name'],
        _gender = map['gender'],
        _birth = map['birth'] as DateTime,
        _license = map['license'] as DateTime,
        _weight = double.parse(map['weight']),
        _size = int.parse(map['size']);

  User.fromSnapshot(DocumentSnapshot snapshot)
      : this.fromMap(snapshot.data, ref: snapshot.reference);

  String get name => _name;
  String get gender => _gender;
  DateTime get birth => _birth;
  DateTime get license => _license;
  double get weight => _weight;
  int get size => _size;
}

So the problem is quite solved. It should be nice to know why the previous way to store was not OK.

Share:
4,814
Barracud Apps
Author by

Barracud Apps

Belgian company created in November 2018 developing internal mobile applications. Team : Pierre LAMOTTE Alexia SCOURNEAU Cédric LEGRAND Simon ROMAINVILLE Website Facebook YouTube Twitter Instagram RedBubble MyTip

Updated on December 10, 2022

Comments

  • Barracud Apps
    Barracud Apps over 1 year

    I'm looking for some help for an app my team and I are working on. We are facing the following problem for weeks :

    flutter type 'Timestamp' is not a subtype of type 'DateTime'
    

    We want to get these user data from Cloud Firestore:

    • birth [DateTime]
    • gender [String]
    • license [DateTime]
    • name [String]
    • size [String]
    • weight [String]

    Only birth and license are stored as [Timestamp] in Cloud Firestore so we parse these data to [DateTime].

    Here's our code to get user's data :

    import 'package:cloud_firestore/cloud_firestore.dart';
    
    class User{
      final String _name;
      final String _gender; // 'homme' or 'femme' or 'autre'
      final DateTime _birth;
      final DateTime _license;
      final double _weight;
      final int _size;
      DocumentReference ref;
    
      User(this._birth,this._gender,this._license,this._name,this._size,this._weight,this.ref);
    
      User.fromMap(Map<String, dynamic> map, {this.ref})
          : assert(map['name'] != null && map['gender'] != null && map['birth'] != null && map['weight'] != null && map['size'] != null),
            _name = map['name'],
            _gender = map['gender'],
            _birth = map['birth'] as DateTime,
            _license = map['license'] as DateTime,
            _weight = double.parse(map['weight']),
            _size = int.parse(map['size']);
    
      User.fromSnapshot(DocumentSnapshot snapshot)
          : this.fromMap(snapshot.data, ref: snapshot.reference);
    
      String get name => _name;
      String get gender => _gender;
      DateTime get birth => _birth;
      DateTime get license => _license;
      double get weight => _weight;
      int get size => _size;
    }
    

    And here's where we call these functions and where the issue seems to appear :

    import 'package:bappsalcolit/pages/homepage.dart';
    import 'package:flutter/material.dart';
    import 'package:bappsalcolit/sign_in/auth.dart';
    import 'package:bappsalcolit/sign_in/log_page.dart';
    import 'package:bappsalcolit/ads_display.dart';
    import 'package:bappsalcolit/dbase/model/global_info.dart';
    
    import 'package:cloud_firestore/cloud_firestore.dart';
    
    User currentUser = User(null, null, null, null, null, null, null);
    
    class RootPage extends StatefulWidget {
      RootPage({this.auth});
    
      final AuthImpl auth;
    
      @override
      State<StatefulWidget> createState() => new _RootPageState();
    }
    
    enum AuthStatus {
      NOT_DETERMINED,
      NOT_SIGNED_IN,
      SIGNED_IN,
    }
    
    class _RootPageState extends State<RootPage> {
      AuthStatus authStatus = AuthStatus.NOT_DETERMINED;
      String _userID = "";
    
      @override
      void initState(){
        super.initState();
        Ads.hideBanner();
        widget.auth.getCurrentUser().then((user) {
          setState(() {
            if(user != null) {
              _userID = user?.uid;
            }
            authStatus =
            user?.uid == null ? AuthStatus.NOT_SIGNED_IN : AuthStatus.SIGNED_IN;
          });
        });
      }
    
      void _signedIn() {
        widget.auth.getCurrentUser().then((user){
          setState(() {
            _userID = user?.uid.toString();
          });
        });
        setState(() {
          authStatus = AuthStatus.SIGNED_IN;
        });
      }
    
      void _signedOut() {
        setState(() {
          authStatus = AuthStatus.NOT_SIGNED_IN;
          _userID = "";
        });
      }
    
      Widget _buildWaitingScreen() {
        return Scaffold(
          body: Container(
            height: 20.0,
            width: 20.0,
            alignment: Alignment.center,
            child: CircularProgressIndicator(),
          ),
        );
      }
    
      //========== Here's where the problem seems to appear ==========\\
      gettingSnapshots(){
        Firestore db = Firestore.instance;
        DocumentSnapshot userDS;
        db.collection('users').document(_userID).snapshots().listen((ds) async{
          if (ds.exists) {
            userDS = await db.collection('users').document(_userID).get();
            try {
              currentUser = User.fromSnapshot(userDS);
            } catch (e) {
              print('Error 1131: $e');
            }
          }
        });
      }
    
      @override
      Widget build(BuildContext context) {
        switch (authStatus) {
          case AuthStatus.NOT_SIGNED_IN:
            return new SignIn(
              auth: widget.auth,
              onSignedIn: _signedIn,
            );
            break;
          case AuthStatus.SIGNED_IN:
            if(_userID.length > 0 && _userID != null) {
              gettingSnapshots();
              return new HomePage(
                userID: _userID,
                auth: widget.auth,
                onSignedOut: _signedOut,
              );
            }
            break;
          case AuthStatus.NOT_DETERMINED:
            return _buildWaitingScreen();
            break;
        }
        return _buildWaitingScreen();
      }
    }
    

    The issue only occurs on iOS. Everything is OK on Android.

    The problem should not come from the link between Cloud Firestore and the app because we can get other stored information.

  • Barracud Apps
    Barracud Apps about 5 years
    Edit: Another way to solve the problem has been described here : stackoverflow.com/questions/52996707/…