1

I am using Firebase in my React Native app. I have a collection of users and in that, I have documents and the ids of the documents are custom (using users' phone numbers as ids) and in that, I have blocked users array field in which I will add the users who are blocked by the user. I want to show the list where user can only see the users who are not blocked.

I am getting all the users list and I want to filter them and fetch only the people not blocked by the user.

var getUsersList = async() => {
  const findUser = await firestore().collection('users').get();
  if (findUser.docs[0] != undefined && findUser.docs[0]._exists){
    setUserList(findUser.docs)
  }
}
Zsolt Meszaros
  • 21,961
  • 19
  • 54
  • 57
  • Hey there. Can you provide an example for this line?: "I want to show the list where user can only see the users who are not blocked." I am finding it hard to understand. Does the list of block users contain numbers? or is it an array of subcollection of users?. – Antonio Ramirez Jan 05 '21 at 23:53
  • the app is like social media like we have in facebook user can block any other user so on the main page I am showing the users friends cards and have block friend option when a user block any of his friend then that friend will not seen in those list –  Jan 06 '21 at 16:59
  • The code you have added seems as you mentioned, getting all the users but what you have tried to filter them? – Puteri Jan 06 '21 at 18:29

1 Answers1

0

I understand that your firestore collection is similar to this one:

enter image description here

If that is the case, then I have structured your requirement in the three functions below:

1.readBlockedNumbers to return the array of blocked numbers that the user has.
2.show_nonBlockedUsersthat receives the array of the blocked numbers from the previous method and displays the users who are not in this array.
3. test to coordinate the execution of the above two methods.

const admin = require('firebase-admin');
const serviceAccount = require('/home/keys.json');

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount)
});

const db = admin.firestore();

async function readBlockedNumbers(docId){
  const userRef = db.collection('users').doc(docId);
  const doc = await userRef.get();
  if (!doc.exists) {
    console.log('No such document!');
    return [];
  } 
  else 
  {
    return doc.data()['blocked_numbers'];
  }

async function show_nonBlockedUsers(blocked_users){
  console.log('Array length:', blocked_users.length);
  
  if(blocked_users.length == 0)
  return;
  
  const userRef = db.collection('users');
  const snapshot = await userRef
    .where(admin.firestore.FieldPath.documentId(), 'not-in', blocked_users)
    .get();
  
  if (snapshot.empty) {
    console.log('No matching documents.');
    return;
  }  
  
  snapshot.forEach(doc => {
    console.log(doc.id, '=>', doc.data());
  });
}

async function test(){
  const docId = '202-555-0146';
  //'202-555-0102'
  const blocked_users = await readBlockedNumbers(docId);
  await show_nonBlockedUsers(blocked_users);
}

Important here is how to use the not-in operator and the method admin.firestore.FieldPath.documentId().
I have found the not-in operator here and the method firebase.firestore.FieldPath.documentId() referenced in this other stackoverflow question since the id cannot be passed like the other document fields in the where clause.

Please refer to the firebase documentation as well for the limitations of the not-in operator.

I hope you find this useful.

Antonio Ramirez
  • 943
  • 6
  • 15