flutter firestore paginate results - flutter

bool hasMore = true;
bool isLoading = false;
DocumentSnapshot nextDocument;
DocumentSnapshot previousDocument;
getProducts() async {
if (!hasMore) {
print('No More Products');
return;
}
if (isLoading) {
return;
}
setState(() {
isLoading = true;
});
QuerySnapshot querySnapshot;
if (nextDocument == null) { // First time to get products
querySnapshot = await firestore
.collection('products')
.orderBy('name')
.limit(10)
.getDocuments();
} else {
querySnapshot = await firestore
.collection('products')
.orderBy('name')
.startAfterDocument(nextDocument)
.limit(10)
.getDocuments();
print(1);
}
if (querySnapshot.documents.length < 10) {
hasMore = false;
}
nextDocument = querySnapshot.documents[querySnapshot.documents.length - 1];
previousDocument = querySnapshot.documents[querySnapshot.documents.length - 19];
products.addAll(querySnapshot.documents);
setState(() {
isLoading = false;
});
}
try to use this code i don't do this before but i just try to help youtry to use this code i don't do this before but i just try to help youtry to use this code i don't do this before but i just try to help youtry to use this code i don't do this before but i just try to help youtry to use this code i don't do this before but i just try to help youtry to use this code i don't do this before but i just try to help youtry to use this code i don't do this before but i just try to help you

Related

Flutter - Null check operator used on a null value

I am trying to retrieve user data using a DocumentSnapshot. However I am getting a casterror because the instance that I created is pointing to null. So I tried calling the method getUserProfileData in the initState method to see if it could assign a value to my DocumentSnapshot instance but I still get that error. Please may anyone kindly help.
//DocumentSnapshot instance that is null
DocumentSnapshot? userDocument;
getUserProfileData() {
FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.snapshots()
.listen((event) {
userDocument = event;
});
}
#override
void initState() {
getUserProfileData();
//This is where the castError occurs because userDocument is null
nameController.text = userDocument!.get('name');
userNameController.text = userDocument!.get('username');
try {
descriptionController.text = userDocument!.get('description');
} catch (e) {
descriptionController.text = '';
}
try {
followers = userDocument!.get('followers').length;
} catch (e) {
followers = 0;
}
try {
following = userDocument!.get('following').length;
} catch (e) {
following = 0;
}
}
It would be better to use StreamBuilder for firstore-snapshot.
late final stream = FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.snapshots();
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: stream,
builder: (context, snapshot) {....},
);
}
Also error can be bypass like
getUserProfileData() {
FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.snapshots()
.listen((event) {
userDocument = event;
/// all those stuff here
nameController.text = userDocument!.get('name');
userNameController.text = userDocument!.get('username');
..........
Try use async/await for getUserProfileData() function
getUserProfileData() async {
await FirebaseFirestore.instance
.collection('users')
.doc(FirebaseAuth.instance.currentUser!.uid)
.snapshots()
.listen((event) {
userDocument = event;
});
}
#override
void initState() {
getUserProfileData();
// Replace with default value case userDocument is null
nameController.text = userDocument!.get('name') ?? "";
userNameController.text = userDocument!.get('username') ?? "";
try {
descriptionController.text = userDocument!.get('description') ?? "";
} catch (e) {
descriptionController.text = '';
}
try {
followers = userDocument!.get('followers').length ?? 0;
} catch (e) {
followers = 0;
}
try {
following = userDocument!.get('following').length ?? 0;
} catch (e) {
following = 0;
}
}
Async determines that a method will be asynchronous, that is, it will not return something immediately, so the application can continue executing other tasks while processing is not finished.
await serves to determine that the application must wait for a response from a function before continuing execution. This is very important because there are cases where a function depends on the return of another.
a ?? b means that if the value of a is null, the value b will be assigned

Pull to refresh package in flutter for pagination purpose

Hello Readers I am new in flutter and i want to do pagination, for pagination I am using one package which name is "pull to refersh".
Problems :
I have total 6 post and per page limits are 3.
1)When I reached at the end of list then api will call and set current page variable value is 2 and it will load all data of page 2 as a new list, but i want to merge page 2 data into same list... (Pagination like facebook instagram etc).
2)My another problem is when i pull for refersh, page is refersh perfectly and it will go to the first page but problem is, when i again go at the end of list it shows me no more data(which means page 2 api is not working)
I have one condition like if else:- "hasNextPage" this variable getting from api and the response is 1 or 2, if response is 1 then there further page after current page and if is 0 then there is no page after current page.
I am posting my code and api link also can you please help me.
Method for get data from API
int currentPage = 1;
bool isRefersh = false;
final RefreshController refreshController = RefreshController();
Future<UserPost> getUserPost() async {
var url =
"LINK=$currentPage";
var response = await http.get(Uri.parse(url));
var jsondata = jsonDecode(response.body.toString());
var _apiData = UserPost.fromJson(jsondata);
if (response.statusCode == 200) {
print("******getUserPost API");
print("current page****$currentPage");
print("hasnext page ${_apiData.hasNextPage}");
print(jsondata);
if(isRefersh == true){
setState((){
//currentPage = 1;
isRefersh = false;
});
refreshController.refreshCompleted();
return UserPost.fromJson(jsondata);
}
else{
print("//////////////// has next page");
print(_apiData.hasNextPage.toString());
if(_apiData.hasNextPage == 0){
refreshController.loadNoData();
return UserPost.fromJson(jsondata);
}else{
}
return UserPost.fromJson(jsondata);
}
} else {
return UserPost.fromJson(jsondata);
}
}
Method for pull to Refersh
onRefresh: () async{
await Future.delayed(Duration(milliseconds: 1000));
setState(() {
isRefersh = true;
currentPage = 1;
});
},
Method for Pagination
onLoading: () async {
if(snapshot.data!.hasNextPage == 0){
refreshController.loadNoData();
}else{
setState(() {
currentPage++;
});
await Future.delayed(Duration(milliseconds: 1000));
refreshController.loadComplete();
}
},
I Hope it's help you
try this way :-
final RefreshController refreshController =
RefreshController(initialRefresh: true);
Future<bool> getPassengerData({bool isRefresh = false}) async {
if (isRefresh) {
currentPage = 1;
} else {
if (currentPage >= totalPages) {
refreshController.loadNoData();
return false;
}
}
final Uri uri = Uri.parse(
"api url=$currentPage&size=10");
final response = await http.get(uri);
if (response.statusCode == 200) {
final result = passengersDataFromJson(response.body);
if (isRefresh) {
passengers = result.data;
}else{
passengers.addAll(result.data);
}
currentPage++;
totalPages = result.totalPages;
print(response.body);
setState(() {});
return true;
} else {
return false;
}
}
Method for pull to Refersh
onRefresh: () async {
final result = await getPassengerData(isRefresh: true);
if (result) {
refreshController.refreshCompleted();
} else {
refreshController.refreshFailed();
}
},
Method for onLoading:
onLoading: () async {
final result = await getPassengerData();
if (result) {
refreshController.loadComplete();
} else {
refreshController.loadFailed();
}
},
Try this way.
when you get the response in second page just create new list with previous list.
i.e var newData = [...?dummyData.data, ...?_apiData.data];
than return this same list.
UserPostModel dummyData = UserPostModel();
Future<UserPostModel> getUserPost() async {
var url =
"*****?page=$currentPage";
var response = await http.get(Uri.parse(url));
var jsondata = jsonDecode(response.body.toString());
var _apiData = UserPostModel.fromJson(jsondata);
var newData = [...?dummyData.data, ...?_apiData.data];
//totalPage = _apiData.totalPages as int?;
if (response.statusCode == 200) {
if (isRefersh == true) {
setState(() {
isRefersh = false;
});
refreshController.refreshCompleted();
} else {
if (_apiData.hasNextPage == 0) {
refreshController.loadNoData();
} else {
refreshController.loadComplete();
}
}
dummyData.data = newData;
return dummyData;
} else {
return dummyData;
}
}

How to query firestore in real time in flutter

I have this code
checkUserValue(String user) async {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
await _firestore.runTransaction((transaction) async {
DocumentReference userRef = _firestore
.collection("users")
.where("id", isEqualTo: "hhjhgjhfhgfhgfh");
DocumentSnapshot snapshot = await transaction.get(userRef);
String docc = snapshot.get("username");
print(docc);
if (docc == null) {
_userExist = false;
} else {
_userExist = true;
}
});
}
But am faced with this issue,
Please I need solution
where(...) function return Query<Map<String, dynamic>> not the DocumentReference
You need to pass the document path (DocumentReference) in the get() method. So, specify the correct document path
DocumentReference userRef = _firestore.collection('users').doc('hhjhgjhfhgfhgfh');
checkUserValue(String user) async {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
await _firestore.runTransaction((transaction) async {
DocumentReference userRef =
_firestore.collection('users').doc('hhjhgjhfhgfhgfh');
DocumentSnapshot snapshot = await transaction.get(userRef);
String docc = snapshot.get('username');
print(docc);
if (docc == null) {
_userExist = false;
} else {
_userExist = true;
}
});
}

Flutter, Couldn't get firebase query snapshots

I fetching data from firebase performing a query and updating a bool based on the query. But my code doesn't work. I tried printing the snapshots but I get "Instance of '_ControllerStream<QuerySnapshot<Map<String, dynamic>>>'" in the terminal how do I solve this.
Stream<QuerySnapshot<Map<String, dynamic>>>namees = await FirebaseFirestore
.instance
.collection('lender')
.doc(auth.currentUser!.email)
.collection('borrowers')
.where('Name', isEqualTo: textfieldname).snapshots();
print(namees);
if (namees.isEmpty == true) {
setState(() {
isThere = true;
});
} else {
setState(() {
isThere = false;
});
}

Flutter function inside shared preferences

Hi all i want to execute a function on load of a page and i have set this:
void initState(){
super.initState();
getPref();
}
getPref() async {
SharedPreferences myPref = await SharedPreferences
.getInstance();
setState(() {
myId = myPref.getString("keyPrefUserId");
myFullName = myPref.getString("keyPrefDisplayName");
myAvatar = myPref.getString("keyPrefPhotoUrl");
customId = myPref.getString("keyPrefUserId");
isLoading = false;
});
await updateFeedNotificationNumber();
}
updateFeedNotificationNumber() async{
QuerySnapshot eventsQuery = await activityFeedRef
.document(myid)
.collection('feedItems')
.where('isRead', isEqualTo: false)
.getDocuments();
eventsQuery.documents.forEach((DocumentSnapshot doc) {
doc.reference.updateData({'isRead' : true });
});
}
But it changes to true if i press every page.. not only to this one. Any idea about that?