I’m trying to achieve a query with Firestore to show to my main user, user nears to him that he hasn’t seen yet !
Let’s call that function « getNearUsers », and my main user « toto ».
Sorry for the long title I could not find a more specific yet meaningful title.
Like Tinder Toto can swipe users, each swiped user is stored in Toto document, in an array of userId called « likes ». To make geopoints and location queryable, I use GeoFirestorejs in a Firebase Cloud Function. This allow me to query user based on their « lastLocation ».
Users location are updated then they use the app, so for the same user each call to « getNearUsers » can give me different users even if toto haven’t « swipe » no one.
Here the function :
export const nearToMe = functions.https.onRequest(async (req, res) => {
const firestore = admin.firestore();
const collection = firestore.collection('users');
let limitQuery = collection.limit(50);
const userId = req.body.userId;
const geofirestore: GeoFirestore = new GeoFirestore(firestore);
const geoUsersCollection: GeoCollectionReference = geofirestore.collection('users');
const userDocs = await geoUsersCollection.where('userId', '==', userId).get();
const user = userDocs.docs[0].data();
const userLoc = user.lastLocation;
const userLikes: Array<String> = user.likes;
const matchList = Array<any>();
if(req.body.startAfter){
limitQuery = limitQuery.startAfter(req.body.startAfter);
}
const query = new GeoQuery(limitQuery).near({
center: new admin.firestore.GeoPoint(userLoc.latitude, userLoc.longitude),
radius: 10000
});
const nearUsers = await query.get();
nearUsers.docs.forEach(nearUser => {
const nearUserId = nearUser.data().userId;
if (userLikes.indexOf(nearUserId) < 0 && nearUserId != userId) {
matchList.push(nearUser.data());
}
});
res.send(matchList);
});
I want to limit the numbers of users returned by the function, but I can’t do that at query time because I do not know how many users my user has already « swipe » without getting the list of nears users first (based on the fact that in Firestore you can not find items that are NOT in an array, or not exist). And this is my problem.
If I want to display 10 near users to Toto, I have to query more to be able to have some users that Toto haven’t seen in it. I could use a query cursor and save it to search users after this cursor, but like said earlier, the users list of « getNearUsers » can give me different users, the list won’t be the same, the order won’t be neither.
At T time, « getNearUsers » could return User1, User4. So I get a cursor at User4. But at T+1, the func can return User2, User3, User 4… So the cursor will be useless because that’s won’t return 2 and 3. Right ?
And more Toto swipe users, more his list become big and more my query need to retrieve a large set of data to be sure to be able to display users to Toto, or as an alternative I could launch several times the query with a cursor until I get a proper numbers of users…But the issue remains the same.
I’m a bit lost, and still don’t know yet if this kind of needs/query is doable easily in Firestore. If you think of a better Document Modeling, I’ll be happy to change it.