颤振问题:“时间戳”类型不是“日期时间”类型的子类型
Posted
技术标签:
【中文标题】颤振问题:“时间戳”类型不是“日期时间”类型的子类型【英文标题】:Flutter issue: type 'Timestamp' is not a subtype of type 'DateTime' 【发布时间】:2019-08-05 19:04:12 【问题描述】:我正在为我的团队和我正在开发的应用寻求帮助。数周以来我们都面临以下问题:
flutter type 'Timestamp' is not a subtype of type 'DateTime'
我们希望从 Cloud Firestore 获取这些用户数据:
出生 [日期时间] 性别 [字符串] 许可证 [日期时间] 名称[字符串] 大小 [字符串] 重量 [字符串]只有 birth 和 license 作为 [Timestamp] 存储在 Cloud Firestore 中,因此我们将这些数据解析为 [DateTime]。
这是我们获取用户数据的代码:
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;
这是我们调用这些函数的地方以及问题似乎出现的地方:
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();
此问题仅发生在 ios 上。在 android 上一切正常。
问题不应该来自 Cloud Firestore 和应用程序之间的链接,因为我们可以获取其他存储的信息。
【问题讨论】:
【参考方案1】:在我使用的项目中
birth: parsedJson['birth'].toDate()
而且效果很好,这是另一种选择。
【讨论】:
【参考方案2】:我们解决了这个问题。
我们没有对接收到的值采取行动,而是将我们的 [DateTime] 值存储为解析为 [String]。所以我们将这些参数解析回 [DateTime] 与上面描述的相同:
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;
这样问题就解决了。应该很高兴知道为什么以前的存储方式不好。
【讨论】:
编辑:这里描述了另一种解决问题的方法:***.com/questions/52996707/…【参考方案3】:我是新来的,不知何故我对上面的答案有一个心理障碍。
但是,我发现这对我有用。
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 Timestamp).toDate(),
_license =(map['license'] as Timestamp).toDate(),
_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;
【讨论】:
以上是关于颤振问题:“时间戳”类型不是“日期时间”类型的子类型的主要内容,如果未能解决你的问题,请参考以下文章