Flutter - 如何使用 Firebase Auth 在 streambuilder 中访问未来的价值
Flutter - how to access the value of a future inside a streambuilder, with Firebase Auth
我正在为我正在构建的基于订阅的应用程序使用 Firebase 身份验证,并使用云功能和自定义声明,我确保用户只有在订阅有效时才能登录。
我的应用程序有一个登陆页面,用于检查用户是否已登录,如果已登录,他们将被带到应用程序主页。如果没有,他们将显示登录屏幕。这是它的代码:
class LandingPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final auth = Provider.of<AuthBase>(context, listen: false);
return StreamBuilder<User?>(
stream: auth.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
User? user = snapshot.data;
user?.reload();
user = snapshot.data;
if (user == null || user.emailVerified == false) {
return SignInHomePage.create(context);
}
return Provider<User?>.value(
value: user,
child: DisclaimerAcceptanceHomeScreen(
userName: user.displayName,
),
);
} else {
return Scaffold(
body: Center(
child: PlatformCircularProgressIndicator(),
),
);
}
});
}
}
这非常适合获取用户数据并显示相关屏幕。唯一的问题是,我不知道如何将用户的订阅状态添加到此,以确保只有具有有效订阅的用户才会被定向到应用程序的主页。订阅状态自定义声明被 return 编辑为未来。理论上我想使用这样的东西:
final idTokenResult =
await FirebaseAuth.instance.currentUser?.getIdTokenResult(true);
然后:
idTokenResult?.claims!['status']
return 用户进入登录屏幕的理想情况是:
user == null || user.emailVerified == false || idTokenResult?.claims!['status'] != 'active'
这确实在 async/await 函数中起作用,但您会看到我的登录页面是一个无状态小部件并且不是异步的。
如何修改着陆页代码,以允许我获得 Future 'status' 自定义声明值?我将不胜感激对此的任何建议。谢谢!
您是否考虑过在对 getIdTokenResult
的调用周围使用 FutureBuilder
?
或者,您可以在 FirebaseAuth.instance.idTokenChanges()
上使用 StreamBuilder
来获得 ID 令牌所有更新的通知。
根据 Frank 的评论,我修改了我的 StreamBuilder
以包含 FutureBuilder
,其中 future 是 getIdTokenResult(true)
函数。这就是上面的代码,按照描述进行了修改:
class LandingPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final auth = Provider.of<AuthBase>(context, listen: false);
return StreamBuilder<User?>(
stream: auth.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
User? user = snapshot.data;
user?.reload();
user = snapshot.data;
return FutureBuilder<IdTokenResult>(
future: user?.getIdTokenResult(true),
builder: (
BuildContext context,
AsyncSnapshot<IdTokenResult> snapshotData,
) {
if (user == null ||
user.emailVerified == false ||
snapshotData.data?.claims!['status'] != 'active') {
return SignInHomePage.create(context);
} else {
return Provider<User?>.value(
value: user,
child: DisclaimerAcceptanceHomeScreen(
userName: user.displayName,
),
);
}
},
);
} else {
return Scaffold(
body: Center(
child: PlatformCircularProgressIndicator(),
),
);
}
});
}
}
这让我可以在允许用户访问应用程序之前检查用户的订阅状态。
我正在为我正在构建的基于订阅的应用程序使用 Firebase 身份验证,并使用云功能和自定义声明,我确保用户只有在订阅有效时才能登录。
我的应用程序有一个登陆页面,用于检查用户是否已登录,如果已登录,他们将被带到应用程序主页。如果没有,他们将显示登录屏幕。这是它的代码:
class LandingPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final auth = Provider.of<AuthBase>(context, listen: false);
return StreamBuilder<User?>(
stream: auth.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
User? user = snapshot.data;
user?.reload();
user = snapshot.data;
if (user == null || user.emailVerified == false) {
return SignInHomePage.create(context);
}
return Provider<User?>.value(
value: user,
child: DisclaimerAcceptanceHomeScreen(
userName: user.displayName,
),
);
} else {
return Scaffold(
body: Center(
child: PlatformCircularProgressIndicator(),
),
);
}
});
}
}
这非常适合获取用户数据并显示相关屏幕。唯一的问题是,我不知道如何将用户的订阅状态添加到此,以确保只有具有有效订阅的用户才会被定向到应用程序的主页。订阅状态自定义声明被 return 编辑为未来。理论上我想使用这样的东西:
final idTokenResult =
await FirebaseAuth.instance.currentUser?.getIdTokenResult(true);
然后:
idTokenResult?.claims!['status']
return 用户进入登录屏幕的理想情况是:
user == null || user.emailVerified == false || idTokenResult?.claims!['status'] != 'active'
这确实在 async/await 函数中起作用,但您会看到我的登录页面是一个无状态小部件并且不是异步的。
如何修改着陆页代码,以允许我获得 Future 'status' 自定义声明值?我将不胜感激对此的任何建议。谢谢!
您是否考虑过在对 getIdTokenResult
的调用周围使用 FutureBuilder
?
或者,您可以在 FirebaseAuth.instance.idTokenChanges()
上使用 StreamBuilder
来获得 ID 令牌所有更新的通知。
根据 Frank 的评论,我修改了我的 StreamBuilder
以包含 FutureBuilder
,其中 future 是 getIdTokenResult(true)
函数。这就是上面的代码,按照描述进行了修改:
class LandingPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final auth = Provider.of<AuthBase>(context, listen: false);
return StreamBuilder<User?>(
stream: auth.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
User? user = snapshot.data;
user?.reload();
user = snapshot.data;
return FutureBuilder<IdTokenResult>(
future: user?.getIdTokenResult(true),
builder: (
BuildContext context,
AsyncSnapshot<IdTokenResult> snapshotData,
) {
if (user == null ||
user.emailVerified == false ||
snapshotData.data?.claims!['status'] != 'active') {
return SignInHomePage.create(context);
} else {
return Provider<User?>.value(
value: user,
child: DisclaimerAcceptanceHomeScreen(
userName: user.displayName,
),
);
}
},
);
} else {
return Scaffold(
body: Center(
child: PlatformCircularProgressIndicator(),
),
);
}
});
}
}
这让我可以在允许用户访问应用程序之前检查用户的订阅状态。