【发布时间】:2021-07-02 13:13:32
【问题描述】:
目前,我们正在使用 Firebase 在我们的应用程序上实现简单的聊天。
我们使用 Riverpod 处理应用程序的启动和身份验证。
启动过程如下:
@override
Widget build(BuildContext context) {
LocalNotificationService()
.handleApplicationWasLaunchedFromNotification(_onSelectNotification);
LocalNotificationService().setOnSelectNotification(_onSelectNotification);
_configureDidReceiveLocalNotification();
// final navigator = useProvider(navigatorProvider);
final Settings? appSettings = useProvider(settingsNotifierProvider);
final bool darkTheme = appSettings?.darkTheme ?? false;
final LauncherState launcherState = useProvider(launcherProvider);
SystemChrome.setEnabledSystemUIOverlays(
<SystemUiOverlay>[SystemUiOverlay.bottom],
);
return MaterialApp(
title: 'Thesis Cancer',
theme: darkTheme ? ThemeData.dark() : ThemeData.light(),
navigatorKey: _navigatorKey,
debugShowCheckedModeBanner: false,
home: Builder(
builder: (BuildContext context) => launcherState.when(
loading: () => SplashScreen(),
needsProfile: () => LoginScreen(),
profileLoaded: () => MainScreen(),
),
),
);
}
目前,我们只启用从主屏幕和房间屏幕注销,如下所示:
ListTile(
leading: const Icon(Icons.exit_to_app),
title: const Text('Çıkış yap'),
onTap: () =>
context.read(launcherProvider.notifier).signOut(),
),
signOut 在哪里:
Future<void> signOut() async {
tokenController.state = '';
userController.state = User.empty;
await dataStore.removeUserProfile();
_auth.signOut();
state = const LauncherState.needsProfile();
}
问题是,每次我们访问RoomsPage 并从中注销或从主页(从房间返回)时,我们都会遇到与 firebase 相同的问题:
The caller does not have permission to execute the specified operation.。
当然,signout 会关闭 Firebase,因此 Firebase 会抛出此错误;但是,假设从 RoomsScreen 出来后(即使返回主屏幕也会发生),这个小部件被释放,因此连接应该被关闭,释放,但它似乎仍然在内存中。
RoomPage画面如下:
class RoomsPage extends HookWidget {
@override
Widget build(BuildContext context) {
final AsyncValue<List<fc_types.Room>> rooms =
useProvider(roomsListProvider);
return Scaffold(
appBar: Header(
pageTitle: "Uzmanlar",
leading: const BackButton(),
),
endDrawer: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 275),
child: SideMenu(),
),
body: rooms.when(
data: (List<fc_types.Room> rooms) {
if (rooms.isEmpty) {
return Container(
alignment: Alignment.center,
margin: const EdgeInsets.only(
bottom: 200,
),
child: const Text('No rooms'),
);
}
return ListView.builder(
itemCount: rooms.length,
itemBuilder: (
BuildContext context,
int index,
) {
final fc_types.Room room = rooms[index];
return GestureDetector(
onTap: () => pushToPage(
context,
ChatPage(
room: room,
),
),
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
child: Row(
children: <Widget>[
Container(
height: 40,
margin: const EdgeInsets.only(
right: 16,
),
width: 40,
child: ClipRRect(
borderRadius: const BorderRadius.all(
Radius.circular(20),
),
child: Image.network(room.imageUrl ?? ''),
),
),
Text(room.name ?? 'Room'),
],
),
),
);
},
);
},
loading: () => const Center(
child: CircularProgressIndicator(),
),
error: (Object error, StackTrace? stack) => ErrorScreen(
message: error.toString(),
actionLabel: 'Home',
onPressed: () => Navigator.of(context).pop(),
),
),
);
}
}
而且提供者很简单:
final AutoDisposeStreamProvider<List<fc_types.Room>> roomsListProvider =
StreamProvider.autoDispose<List<fc_types.Room>>(
(_) async* {
final Stream<List<fc_types.Room>> rooms = FirebaseChatCore.instance.rooms();
await for (final List<fc_types.Room> value in rooms) {
yield value;
}
},
name: "List Rooms Provider",
);
我想 AutoDispose 构造函数会在小部件被移除时自动处理此提供程序,因此,它应该关闭与 Firebase 的连接(如文档所述)。
这里有什么问题?
我错过了什么?
我应该就此提出问题吗?
【问题讨论】:
标签: firebase flutter firebase-authentication riverpod