使用 Firestore 在 Flutter 中加载配置文件数据的最佳方式是啥?
Posted
技术标签:
【中文标题】使用 Firestore 在 Flutter 中加载配置文件数据的最佳方式是啥?【英文标题】:What is the best way to load profile data in Flutter using Firestore?使用 Firestore 在 Flutter 中加载配置文件数据的最佳方式是什么? 【发布时间】:2021-06-30 08:52:34 【问题描述】:我正在尝试使用 Firestore 加载配置文件数据。我不想每次点击主页都重新加载数据。
我想将此数据存储在类对象中,然后有一个刷新功能,用户可以在第一次初始化配置文件数据后手动调用。我想在调用“主页”小部件时执行此操作,传入我的“ProfileModel”的快照,但它会以相同的方式持续加载这些数据吗?
这是为所选索引调用的导航栏小部件类
class SelectedNavigationBarItem extends StatelessWidget
FirebaseAuth auth;
FirebaseFirestore firestore;
final int currentIndex;
bool hasBeenWelcomed = false;
@override
SelectedNavigationBarItem(
@required this.auth, @required this.firestore, this.currentIndex);
@override
Widget build(BuildContext context)
List<Widget> _widgetOptions = <Widget>[
HomeBarWelcome(
auth: this.auth,
firestore: this.firestore,
welcomed: hasBeenWelcomed),
Text("PlaceHolder1"),
Text("Placeholder2"),
Text("Placeholder3"),
];
return _widgetOptions.elementAt(this.currentIndex);
我正在考虑一种使用 FutureBuilder 或 StreamBuilder 将配置文件数据快照传递给我拥有的 HomePage 类的方法。然后从那里,我会将该快照向下传递到小部件树,但如果我在我的第一个小部件中执行此操作,即 runApp() 调用的小部件,它会持续加载配置文件数据并继续调用 Firestore 以获取配置文件数据吗? 或者它会运行一次,然后放在 HomePage 类中,该类将在第一次 runApp() 调用中返回?
我想我只是想问一下小部件是如何被调用的? runApp() 是否被连续调用,然后每次调用都会沿着小部件路径遍历?还是调用一次,然后 Widget 类从那里处理 Flutter 应用程序的状态,每个 Widget 类根据该 Widget 类中调用的下一个小部件来控制状态? 抱歉,我确信这是一个相当混乱的帖子。但我只是在寻找加载这些数据的正确方法,因为我不希望重复调用 Firestore 来不必要地获取数据。
【问题讨论】:
您必须将您的策略从StatelessWidget
更改为StatefulWidget
,并在initState
部分的State
类中加载资源并将其存储到一个字段中......
@Nima 我已经在这样做了,但我不想在每次调用状态更改时重新加载我的个人资料并调用 firestore。我希望配置文件只加载一次,然后在手动调用时刷新以刷新数据。
【参考方案1】:
由于您使用的是导航栏,您可能希望在 initState 函数中加载数据。一旦构建了导航栏,这将让您的数据加载。为了使用它,首先将您的无状态小部件转换为有状态小部件。它应该放在build ()
上方。这是它的外观:
@override
void initState()
// load your data here
super.initState();
数据将加载一次,您可以将其放到导航栏项目中。我希望这会有所帮助!
【讨论】:
【参考方案2】:我想通了,在我的 MaterialApp 调用的身份验证包装器中,我使用了带有嵌套 FutureBuilders 的 StreamBuilder 来解决我的问题。在此之后,我只是通过我的小部件树传递了变量。
我觉得好像有更好的方法可以做到这一点,但我还没有答案。所以我将使用它,因为它有效。
这是我的 _AuthWrapperState 类:
class _AuthWrapperState extends State<AuthenticationWrapper>
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
Future<ProfileModel> _getProfile() async
return await Database(_firestore).getProfile(uid: _auth.currentUser.uid);
Future<SharedPreferences> _getPrefs() async
return await SharedPreferences.getInstance();
@override
Widget build(BuildContext context)
return StreamBuilder(
stream: AuthService(auth: _auth, firestore: _firestore).user,
builder: (BuildContext context, AsyncSnapshot<User> snapshot)
if (snapshot.connectionState == ConnectionState.active)
if (snapshot.data?.uid == null)
return SignIn(auth: _auth, firestore: _firestore);
else
return FutureBuilder(
future: _getProfile(),
builder: (builder, AsyncSnapshot<ProfileModel> snapshot)
if (snapshot.hasData)
ProfileModel profileModel = snapshot.data;
return FutureBuilder(
future: _getPrefs(),
builder: (context,
AsyncSnapshot<SharedPreferences> snapshot)
if (snapshot.hasData)
return Home(
auth: _auth,
firestore: _firestore,
profileModel: profileModel,
sharedPrefs: snapshot.data,
);
else
return const Scaffold(
body: CircularProgressIndicator(),
);
);
else
return const Scaffold(
body: Center(child: CircularProgressIndicator()));
);
else
return const Scaffold(
body: Center(
child: Text("Loading..."),
),
);
,
);
【讨论】:
以上是关于使用 Firestore 在 Flutter 中加载配置文件数据的最佳方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章
带有 Firebase 托管的 Flutter web 无法从存储中加载图片
在 Flutter 中使用 Cloud Firestore 创建无限列表
如何使用 Firestore 在 Flutter 中搜索文本