我正在嘗試從 firestore 資料庫中列出一些資料。在提取資料時,我得到了這個例外:
======== Exception caught by provider ==============================================================
The following assertion was thrown:
An exception was throw by _MapStream<QuerySnapshot<Map<String, dynamic>>, List<UserModel>?> listened by
StreamProvider<List<UserModel>?>, but no `catchError` was provided.
Exception:
type 'int' is not a subtype of type 'double?'
====================================================================================================
這些是我的資料庫功能:
// users list from snapshot
List<UserModel>? _usersListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.docs.map((doc) {
return UserModel(
uid: doc.get('uid'),
username: doc.get('username') ?? '',
email: doc.get('email') ?? '',
type: doc.get('type') ?? '',
balance: doc.get('balance'),
usertag: doc.get('usertag') ?? '',
connected: doc.get('connected') ?? '',
);
}).toList();
}
// get users stream
Stream<List<UserModel>?> get usersList {
User? user = _auth.currentUser;
UserModel? userModel = _userFromFirebaseUser(user);
final CollectionReference userRef = FirebaseFirestore.instance.collection("users");
final List? connectedList = userModel?.connected;
final Query inList = userRef.where('uid', whereIn: connectedList);
return inList.snapshots().map(_usersListFromSnapshot);
}
這是我的 user.dart:
class UserModel {
String? uid;
String? username;
String? email;
String? type;
double? balance;
String? usertag;
List<dynamic>? connected;
UserModel({this.uid, this.username, this.email, this.type, this.balance, this.usertag, this.connected});
// receive data from the server
factory UserModel.fromMap(map) {
return UserModel(
uid: map['uid'],
username: map['username'],
email: map['email'],
type: map['type'],
balance: map['balance'],
usertag: map['usertag'],
connected: map['connected']
);
}
// send data to the server
Map<String, dynamic> toMap() {
return {
'uid': uid,
'username': username,
'email': email,
'type': type,
'balance': balance,
'usertag': usertag,
'connected': connected,
};
}
}
這是我的串列生成器:
class ConnectedScreen extends StatefulWidget {
const ConnectedScreen({Key? key}) : super(key: key);
@override
_ConnectedScreenState createState() => _ConnectedScreenState();
}
class _ConnectedScreenState extends State<ConnectedScreen> {
User? user = FirebaseAuth.instance.currentUser;
UserModel userModel = UserModel();
@override
void initState() {
super.initState();
FirebaseFirestore.instance
.collection('users')
.doc(user!.uid)
.get()
.then((value) {
userModel = UserModel.fromMap(value.data());
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: customAppBar("Connect Users", "back", ""),
body: Padding(
padding: EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: StreamProvider<List<UserModel>?>.value(
value: AuthService().usersList,
initialData: [],
child: ConnectedListBuilder(),
),
),
),
);
}
}
class ConnectedListBuilder extends StatefulWidget {
const ConnectedListBuilder({Key? key}) : super(key: key);
@override
_ConnectedListBuilderState createState() => _ConnectedListBuilderState();
}
class _ConnectedListBuilderState extends State<ConnectedListBuilder> {
@override
Widget build(BuildContext context) {
final connectedUsers = Provider.of<List<UserModel>?>(context);
if (connectedUsers!.isNotEmpty) {
return Padding(
padding: EdgeInsets.only(top: 8.0),
child: ListView.builder(
itemCount: connectedUsers.length,
itemBuilder: (context, index) {
return ConnectedUserTile(userModel: connectedUsers[index]);
},
),
);
} else if (connectedUsers.isEmpty) {
return Text("List is empty");
}
return Center(
child: CircularProgressIndicator(),
);
}
}
class ConnectedUserTile extends StatelessWidget {
final UserModel? userModel;
const ConnectedUserTile({Key? key, required this.userModel}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(8.0),
child: Card(
margin: EdgeInsets.fromLTRB(20, 6, 20, 0),
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage('https://picsum.photos/100'),
radius: 25,
),
title: Text(
"${userModel!.username}",
style: TextStyle(
color: Colors.black54,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
subtitle: Text(
"${userModel!.usertag}",
style: TextStyle(
color: Colors.black38,
fontSize: 14,
),
),
),
),
);
}
}
有趣的是,這個確切的代碼適用于另一個 ListView,所以我不認為這是資料庫函式的錯誤,但我不知道如何嘗試修復它。我也沒有在互聯網上找到太多有用的資訊,所以我會非常感謝任何幫助。
uj5u.com熱心網友回復:
看起來問題在于決議平衡欄位。在它作業的情況下,余額可能被格式化為雙精度,例如“1.23”,因此當它轉換為地圖時,它被轉換為 a double,它是 的子型別double?。
當它不作業時,它很可能處理整數余額,例如“25” - 然后存盤在映射中的值將具有型別int,它不是 的子型別double?,因為int不是 的子型別double。
要解決此問題,您可以簡單地通過呼叫toDouble()該值來確保始終處理雙精度數。
// receive data from the server
factory UserModel.fromMap(map) {
return UserModel(
uid: map['uid'],
username: map['username'],
email: map['email'],
type: map['type'],
balance: map['balance'].toDouble(), // <- Change this line
usertag: map['usertag'],
connected: map['connected']
);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/495046.html
上一篇:如何使用listView布局添加circleAvatar
下一篇:setState和Hive的問題
