我正在尝试从FirebaseAuth获取当前用户ID,然后将该ID用作Firebase数据库参考路径的一部分。我不确定如何让构建版本等到我的当前用户ID返回并且设置了数据库引用之后。
在下面的代码中,由于watchRef
为空,因此在首次构建时将出错,但是如果引用位置中有数据,则最终将起作用。如果引用位置中没有数据,则侦听器将永远不会setState()
数据,而我只会收到错误消息:
断言失败:第31行pos 12:'query!= I / flutter(11449):null':不正确。
我尝试过FutureBuilders
和Streams
,但是我做的事情不正确。
任何帮助将不胜感激。
class WatchedList extends StatefulWidget {
WatchedList({this.app, this.category});
final FirebaseApp app;
final String category;
@override
State<StatefulWidget> createState() {
return WatchedListState();
}
}
enum Category { watch, read, heard, done }
class WatchedListState extends State<WatchedList> {
int count = 20;
List<FirebaseItem> items = List();
FirebaseItem item;
String title = '';
DatabaseReference watchRef;
FirebaseUser currentUser;
TextStyle textStyle = TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
);
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
item = FirebaseItem('', '', '', '');
_initDB();
}
void _initDB() async {
final FirebaseDatabase database = FirebaseDatabase.instance;
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
currentUser = await firebaseAuth.currentUser();
switch (widget.category) {
case 'watch':
watchRef = database
.reference()
.child('users')
.child(currentUser.uid)
.child('watch');
title = '...WATCHED';
break;
case 'read':
watchRef = database
.reference()
.child('users')
.child(currentUser.uid)
.child('read');
title = '...READ';
break;
case 'heard':
watchRef = database
.reference()
.child('users')
.child(currentUser.uid)
.child('heard');
title = '...HEARD';
break;
case 'done':
watchRef = database
.reference()
.child('users')
.child(currentUser.uid)
.child('done');
title = '...DONE';
break;
}
watchRef.onChildAdded.listen(_onEntryAdded);
watchRef.onChildChanged.listen(_onEntryChanged);
print(currentUser.uid);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
actions: <Widget>[
IconButton(
icon: Icon(Icons.filter_list),
onPressed: () {},
),
// action button
IconButton(
icon: Icon(Icons.settings),
onPressed: () {},
),
],
),
body: Column(
children: <Widget>[
Flexible(
child: FirebaseAnimatedList(
query: watchRef,
itemBuilder: (BuildContext context, DataSnapshot snapshot,
Animation<double> animation, int index) {
return _buildItemSlide(index);
},
),
),
],
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NewSuggestion(
app: widget.app,
),
),
);
},
label: Text('Add Suggestion'),
icon: Icon(Icons.add),
),
);
}
Widget _buildItemCard() {
//Todo - Setting to change between cards and flat list?
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
leading: CircleAvatar(
child: Icon(Icons.ondemand_video),
),
title: Text('Awesome Movie'),
subtitle: Text('Describing awesome movie'),
trailing: GestureDetector(
child: Icon(
Icons.delete,
color: Colors.grey,
),
onTap: () {},
),
onTap: () {
debugPrint('List Tile Tapped');
},
),
);
}
Widget _buildItemSlide(int index) {
return ListTile(
leading: CircleAvatar(
child: Icon(Icons.ondemand_video),
),
title: Text(items[index].title),
subtitle: Text(items[index].body),
trailing: GestureDetector(
child: Icon(
Icons.delete,
color: Colors.grey,
),
onTap: () {
_deleteEntry(context, items[index], index);
},
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ItemDetails(title: items[index].title)));
},
);
}
_onEntryAdded(Event event) {
setState(() {
items.add(FirebaseItem.fromSnapshot(event.snapshot));
});
}
_onEntryChanged(Event event) {
var old = items.singleWhere((entry) {
return entry.key == event.snapshot.key;
});
setState(() {
items[items.indexOf(old)] = FirebaseItem.fromSnapshot(event.snapshot);
});
}
void _deleteEntry(
BuildContext context, FirebaseItem item, int position) async {
await watchRef.child(item.key).remove().then((_) {
setState(() {
items.removeAt(position);
});
});
}
}