将 Firebase 当前用户(作为 Future)作为参数传递给 Stream 中的查询。有可能还是有其他方法?
Posted
技术标签:
【中文标题】将 Firebase 当前用户(作为 Future)作为参数传递给 Stream 中的查询。有可能还是有其他方法?【英文标题】:Passing Firebase current user (as Future) as a parameter to a query in a Stream. Is it possible or is there another way? 【发布时间】:2020-05-02 18:43:03 【问题描述】:我有一个 Stream 从 Firebase 集合 QuerySnapShot 构建一个列表。如果我不将可变数据传递给查询('where' 语句),查询和流构建器工作得很好。但是,我要做的是将 FirebaseAuth.currentUser 作为过滤器传递给我的 Stream 的 where 子句。
我确信我对进行这 2 个单独的异步调用有些不理解。
基本上我需要获取当前经过身份验证的用户的 uid 并将其传递到我的流中的查询中。
我是 Flutter 的超级新手,并且正在快速获得我的印章。已经完全沉浸了大约一个星期。
class Booking
final DateTime startTime;
final DateTime endTime;
final String name;
final String bookingId;
final String truckID;
Booking( this.bookingId, this.truckID, this.startTime, this.endTime, this.name );
// build the booking list from the QuerySnapShot
List<Booking> _bookingListFromSnapshot(QuerySnapshot snapshot)
return snapshot.documents.map((doc)
return Booking(
bookingId: doc.documentID ?? '',
name: doc.data['name'] ?? '',
startTime: doc.data['startTime'].toDate() ?? '',
endTime: doc.data['endTime'].toDate() ?? '',
truckID: doc.data['truckID']
);
).toList();
//asynchronously get the uid of the currentuser from FirebaseAuth
Future<String> inputData() async
final FirebaseUser _aUser = await FirebaseAuth.instance.currentUser();
final String _uid = _aUser.uid.toString();
return _uid;
这是我试图将当前用户传递到流中的地方
//get user specific booking stream
Stream<List<Booking>> get bookings
final _myUserId = inputData();
return bookingCollection
.where("truckID", isEqualTo: _myUserId) //Instance of 'Future<String>'...needs to be the uid of the current user.
.snapshots()
.map(_bookingListFromSnapshot);
// the widget consuming the list
class _BookingListState extends State<BookingList>
@override
Widget build(BuildContext context)
final bookings = Provider.of<List<Booking>>(context) ?? [];
return ListView.builder(
itemCount: bookings.length,
itemBuilder: (context,index)
return BookingTile(booking: bookings[index]);
,
);
编辑以包含用于反馈的 Stream 使用情况(在按照建议将 Stream 包装在 Future 之后)
在我的 home.dart 文件中,我侦听 Stream<List<Booking>>>
,以便构建显示在该页面上的预订列表。在下一个块中,我现在收到一个错误,我无法将参数类型 Stream<List<Booking>>
分配给参数类型 Future<Stream<List<Booking>>>
。编译器建议更改参数类型或将参数强制转换为<Stream<list<Booking>>
完整的编译消息
lib/screens/home/home.dart:38:32: Error: The argument type 'Future<Stream<List<Booking>>>' can't be assigned to the parameter type 'Stream<List<Booking>>'.
- 'Future' is from 'dart:async'.
- 'Stream' is from 'dart:async'.
- 'List' is from 'dart:core'.
- 'Booking' is from 'package:models/booking.dart' ('lib/models/booking.dart').
Try changing the type of the parameter, or casting the argument to 'Stream<List<Booking>>'.
value: DatabaseService().bookings,
home.dart
return StreamProvider<List<Booking>>.value(
value: DatabaseService().bookings,
child: Scaffold( ... ) //Scaffold
); //StreamProvider.value
我尝试将参数value
或参数DatabaseService().value
更改为建议的类型...但我失败了:)
我根据反馈修改了预订获取器
//get user specific booking stream
Future<Stream<List<Booking>>> get bookings async
final _myUserId = await inputData();
print(_myUserId);
return bookingCollection
.where("truckID", isEqualTo: _myUserId) //here is where I want to pass the currentUser
.snapshots()
.map(_bookingListFromSnapshot);
【问题讨论】:
您的函数 inputData() 是异步的,并返回一个 Futureawait
它的结果才能将字符串从 Future 中取出,而您现在没有这样做。async
函数(因为 await
表达式只能在异步函数中使用?
可能。我对 Dart 不是很熟悉,但是在 javascript 中,您只能在异步函数中等待。
【参考方案1】:
是的,您只能在异步函数中使用和等待期货。因此,首先按如下方式更改您的预订获取器。
//get user specific booking stream
Future<Stream<List<Booking>>> get bookings
final _myUserId = await inputData();
return bookingCollection
.where("truckID", isEqualTo: _myUserId) //Instance of 'Future<String>'...needs to be the uid of the current user.
.snapshots()
.map(_bookingListFromSnapshot);
因此,在您提供此流的地方,您需要提供 Future,然后才能从 Future 获取流。
【讨论】:
继续努力……对你的好建议做一点小改动;吸气剂也需要是async
显然现在我需要更改参数“值”类型,或者将参数DatabaseService().bookings
转换为Stream<List<Booking>>
return StreamProvider<List<Booking>>.value( value: DatabaseService().bookings, .... ); //StreamProvider.value
我不清楚如何做到这一点。尝试了一些没有用的方法
感谢@dlohani ...我已经添加了修改后的 getter(供后代使用)和 Steam 侦听器,我在原始帖子中收到了最新错误。以上是关于将 Firebase 当前用户(作为 Future)作为参数传递给 Stream 中的查询。有可能还是有其他方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 中从 Firebase 获取当前用户 ID
如何在 Flutter 中基于 Future 结果构建 Stream?
将 Future<List> 从 Firestore 转换为 List<String> - Flutter Firebase [重复]