I have a Future method (getUserProfileData) that I use to retrieve the number of user posts, the number of followers, the userName, profileImage, etc. It works perfectly for a one time retrieval of the data. If a user adds a post I want the number of posts on the UI to update in real time without having to navigate to a new page and back to refresh the UI. I have reviewed different SO threads, read the documentation and Firestore is working perfectly. The issue is that my limited experience level makes it difficult to figure out how to refactor my code to get the behavior I am looking for. I have removed padding, containers and other layout code to shorten the code submitted. Any help will be appreciated.
class ProfileTabExample extends StatefulWidget {
const ProfileTabExample({
Key? key,
required this.profileID,
required this.userProfileKey,
}) : super(key: key);
final String profileID;
final Key userProfileKey;
@override
State<ProfileTabExample> createState() => _ProfileTabExampleState();
}
class _ProfileTabExampleState extends State<ProfileTabExample> {
Map<String, dynamic> userData = {};
int postLength = 0;
int followers = 0;
int following = 0;
bool isFollowing = false;
bool isLoading = false;
final String currentUser = Auth().currentUser?.uid as String;
@override
void initState() {
super.initState();
_getUserProfileData();
}
Future _getUserProfileData() async {
setState(() {
isLoading = true;
});
try {
DocumentSnapshot<Map<String, dynamic>> userSnap = await FirebaseFirestore
.instance
.collection('users')
.doc(widget.profileID)
.get();
QuerySnapshot<Map<String, dynamic>> postSnap = await FirebaseFirestore
.instance
.collection('posts')
.where('userID', isEqualTo: Auth().currentUser?.uid)
.get();
postLength = postSnap.docs.length;
userData = userSnap.data() as Map<String, dynamic>;
followers = userData['followers'].length;
following = userData['following'].length;
isFollowing = userData['followers'].contains(Auth().currentUser?.uid);
setState(() {});
} catch (e) {
SnackBarUtil.showSnackBar(
context,
e.toString(),
);
}
setState(() {
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return isLoading
? const AdaptiveCircularProgress()
: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
ProfileStatColumn(
count: postLength,
label: ProfilePageString.posts,
),
ProfileStatColumn(
count: followers,
label: ProfilePageString.followers,
),
ProfileStatColumn(
count: following,
label: ProfilePageString.following,
),
],
),
),
],
);
}
}
CodePudding user response:
snapshots method provides stream
, which notifies about changes. Use StreamBuilder to rebuild a widget.
Something like this:
StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('posts').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
...
},
);