I am breaking my head over this problem for several days. The documentation says there is a limitation to use where with equality and orderBy clauses in a single query - https://firebase.google.com/docs/firestore/query-data/order-limit-data
My code is as follows:
FirebaseFirestore.instance
.collection('users')
.where('uid', isNotEqualTo: user.uid)
.orderBy('accountCreationDate', descending: false)
.snapshots()
I have also created a composite index according to other answers in SO
but I am getting this error
"The initial orderBy() field \"[[FieldPath([accountCreationDate]), false]][0][0]\" has to be the
same as the where() field parameter \"FieldPath([uid])\" when an inequality operator is invoked."
The relevant error-causing widget was:
StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>
Based on the suggestion made by others, the best way to achieve my goal is to sort at a front-end level. My issue is I don't really know how to tell the program that an object returned from the firestore snapshot is of type User. The code for user model is below
lass User implements Comparable {
final String user_name;
final String uid;
final String email;
final List followers;
final List following;
final String pictureUrl;
final List bookmarks;
final DateTime accountCreationDate;
const User(
{required this.email,
required this.uid,
required this.user_name,
required this.pictureUrl,
required this.followers,
required this.following,
required this.bookmarks,
required this.accountCreationDate});
Map<String, dynamic> toJson() => {
'user_name': user_name,
'uid': uid,
'email': email,
'pictureUrl': pictureUrl,
'followers': followers,
'following': following,
'bookmarks': bookmarks,
'accountCreationDate': accountCreationDate
};
static User fromSnap(DocumentSnapshot snap) {
var snapshot = snap.data() as Map<String, dynamic>;
return User(
email: snapshot['email'],
user_name: snapshot['user_name'],
uid: snapshot['uid'],
pictureUrl: snapshot['pictureUrl'],
followers: snapshot['followers'],
following: snapshot['following'],
bookmarks: snapshot['bookmarks'],
accountCreationDate: snapshot['accountCreationDate'].toDate());
}
@override
int compareTo(other) {
if (accountCreationDate.isAfter(other.accountCreationDate)) {
return 1;
} else {
return -1;
}
}
}
This is what I am trying to do
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('users')
.where('uid', isNotEqualTo: user.uid)
.snapshots(),
builder: (context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting ||
!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
List sortedUsers = snapshot.data!.docs.map((a,b)=> a.compareTo(b))
...