我正在构建一个应用程序,到目前为止一切正常。直到我单击一个调用此Staful小部件的按钮:
class ToDo1 extends StatefulWidget {
@override
_ToDo1State createState() => _ToDo1State();
}
class _ToDo1State extends State<ToDo1> {
User? user;
late DatabaseService database;
void toggleDone(String key, bool value) {
database.setTodo(key, !value);
}
Future<void> connectToFirebase() async {
final FirebaseAuth _auth = FirebaseAuth.instance;
UserCredential result = await _auth.signInAnonymously();
user = result.user;
database = DatabaseService(user!.uid);
if (!(await database.checkIfUserExists())) {
database.setTodo('To-Do anlegen', false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(
child: Text(
'Stufe 1',
style: TextStyle(
fontStyle: FontStyle.italic,
decoration: TextDecoration.underline),
)),
backgroundColor: Color.fromRGBO(35, 112, 192, 1),
),
body: FutureBuilder(
future: connectToFirebase(),
builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return Center(child: CircularProgressIndicator());
} else {
return StreamBuilder<DocumentSnapshot>(
stream: database.getTodos(),
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
Map<String, dynamic> items =
snapshot.data!.data as Map<String, dynamic>;
return ListView.separated(
separatorBuilder: (BuildContext context, int index) {
return SizedBox(
height: 10,
);
},
padding: EdgeInsets.all(10),
itemCount: items.length,
itemBuilder: (BuildContext, i) {
String key = items.keys.elementAt(i);
return ToDoItem(
key,
items[key]!,
() => toggleDone(key, items[key]),
);
});
}
});
}
},
));
}
}
首先出现加载屏幕,然后我遇到以下错误:
W/DynamiteModule(22637): Local module descriptor class for providerinstaller not found.
I/DynamiteModule(22637): Considering local module providerinstaller:0 and remote module providerinstaller:0
W/ProviderInstaller(22637): Failed to load providerinstaller module: No acceptable module found. Local version is 0 and remote version is 0.
W/om.example.akn(22637): Reducing the number of considered missed Gc histogram windows from 150 to 100
W/om.example.akn(22637): Accessing hidden method Ldalvik/system/CloseGuard;->warnIfOpen()V (greylist,core-platform-api, linking, allowed)
======== Exception caught by widgets library =======================================================
The following _CastError was thrown building StreamBuilder<DocumentSnapshot<Object?>>(dirty, state: _StreamBuilderBaseState<DocumentSnapshot<Object?>, AsyncSnapshot<DocumentSnapshot<Object?>>>#4f0bb):
type '() => Map<String, dynamic>?' is not a subtype of type 'Map<String, dynamic>' in type cast
The relevant error-causing widget was:
StreamBuilder<DocumentSnapshot<Object?>> file:///C:/Users/Lars_/StudioProjects/akne/lib/Fl%C3%A4che%203.1/To-Dos.dart:53:22
When the exception was thrown, this was the stack:
#0 _ToDo1State.build.<anonymous closure>.<anonymous closure> (package:akne/Fl%C3%A4che%203.1/To-Dos.dart:59:72)
#1 StreamBuilder.build (package:flutter/src/widgets/async.dart:546:81)
#2 _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:124:48)
#3 StatefulElement.build (package:flutter/src/widgets/framework.dart:4691:27)
#4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4574:15)
...
====================================================================================================
我认为错误发生在这里:
Map<String, dynamic> items = snapshot.data!.data as Map<String, dynamic>;
这是与Firebase交互的类:
class DatabaseService {
final String userID;
DatabaseService(this.userID);
final CollectionReference userTodos =
FirebaseFirestore.instance.collection('userTodos');
Future setTodo(String item, bool value) async {
return await userTodos.doc(userID).set(
{item:value}, SetOptions(merge: true));
}
Future deleteTodo(String key) async {
return await userTodos.doc(userID).update(
{key: FieldValue.delete(),}
);
}
Future checkIfUserExists() async {
if((await userTodos.doc(userID).get()).exists) {
return true;
}
else {
return false;
}
}
Stream<DocumentSnapshot> getTodos() {
return userTodos.doc(userID).snapshots();
}
}
我希望我已经提供了所有必要的数据,以便解决问题。如果没有,就写信给我,我会试着给你发你需要的材料。
我已经解决了错误!只需在第二个数据后面加上“()”:
Map<String, dynamic> items = snapshot.data!.data() as Map<String, dynamic>;
这是带有错误的旧代码:
Map<String, dynamic> items = snapshot.data!.data as Map<String, dynamic>;
您可以在可空变量中获取值:-
Map<String, dynamic>? items =snapshot.data!.data();
或者您可以像这样在不可为空的变量中获取值:-
Map<String, dynamic> items =snapshot.data!.data()!;