React Native

Querying users in Parse on React Native

Introduction

Some React Native apps need to directly manage your application users or at least be able to list a specific subset of them. Parse has powerful querying tools and they can also be used for your users in your social media app, for example.
In this guide, you’ll learn how to use Parse.Query to perform realistic user querying in your React Native App using Parse JS SDK.

Prerequisites

To complete this tutorial, you will need:

Goal

To build a user querying feature using Parse for a React Native App.

Step 1 - Understanding the Parse.Query class

Any Parse query operation uses the Parse.Query object type, which will help you retrieve specific data from your database throughout your app. It is crucial to know that a Parse.Query will only resolve after calling a retrieve method (like Parse.Query.find or Parse.Query.get), so a query can be set up and several modifiers can be chained before actually being called.

To create a new Parse.Query, you need to pass as a parameter the desired Parse.Object subclass, which is the one that will contain your query results. An example for this guide use-case (Parse.User) can be seen below.

1
2
3
4
// This will create your query
const parseQuery = new Parse.Query(Parse.User);
// The query will resolve only after calling this method
const queryResult = await parseQuery.find();
1
2
3
4
// This will create your query
const parseQuery: Parse.Query = new Parse.Query(Parse.User);
// The query will resolve only after calling this method
const queryResult: [Parse.User] = await parseQuery.find();

You can read more about the Parse.Query class here at the official documentation.

Step 2 - Performing relevant user queries

Let’s now take a look at some relevant queries that you may need to perform when managing or displaying users in your app. First of all, let’s perform a text search query, searching for users whose usernames contain the search value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const doUserQuery = async function () {
  // This value comes from a state variable
  const usernameSearchValue = usernameSearch;
  // This will create your user query
  const parseQuery = new Parse.Query(Parse.User);
  // Several query functions can be set to your Parse,Query, they will
  // only resolve when calling "find", for example
  if (usernameSearchValue !== '') {
    // "contains" will retrieve users whose username contain the searched value, case-sensitive
    parseQuery.contains('username', usernameSearchValue);
    // 
    // or 
    // 
    // for case-insensitive string search, use "matches", that will take into account
    // an regexp for matching, in this case use only "i", which is the regexp modifier
    // for case-insensitive
    parseQuery.matches('username', usernameSearchValue, 'i');
  }
  // Only after calling "find" all query conditions will resolve
  return await parseQuery
    .find()
    .then(async (queriedUsers => {
      // Set the query results to an state variable to retrieve it on your JSX
      // Be aware that empty or invalid queries return as an empty array
      setQueryResults(queriedUsers);
      return true;
    })
    .catch((error) => {
      // Error can be caused by lack of Internet connection, but in most
      // cases "find" will return as an empty array on "then"
      Alert.alert('Error!', error.message);
      setQueryResults([]);
      return false;
    });
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const doUserQuery = async function (): Promise<Boolean> {
  // This value comes from a state variable
  const usernameSearchValue: string = usernameSearch;
  // This will create your user query
  const parseQuery: Parse.Query = new Parse.Query(Parse.User);
  // Several query functions can be set to your Parse,Query, they will
  // only resolve when calling "find", for example
  if (usernameSearchValue !== '') {
    // "contains" will retrieve users whose username contain the searched value, case-sensitive
    parseQuery.contains('username', usernameSearchValue);
    // 
    // or 
    // 
    // for case-insensitive string search, use "matches", that will take into account
    // an regexp for matching, in this case use only "i", which is the regexp modifier
    // for case-insensitive
    parseQuery.matches('username', usernameSearchValue, 'i');
  }
  // Only after calling "find" all query conditions will resolve
  return await parseQuery
    .find()
    .then(async (queriedUsers: [Parse.User]) => {
      // Set the query results to an state variable to retrieve it on your JSX
      // Be aware that empty or invalid queries return as an empty array
      setQueryResults(queriedUsers);
      return true;
    })
    .catch((error: object) => {
      // Error can be caused by lack of Internet connection, but in most
      // cases "find" will return as an empty array on "then"
      Alert.alert('Error!', error.message);
      setQueryResults([]);
      return false;
    });
};

Note that that are at least two different ways to search for a string, each one having its specific applications and advantages. In most cases, you will want to use Parse.Query.matches to ensure case-insensitive results and avoid unexpected behavior in your code.

After performing this query, your user list on your app should be showing something like this:

React Native Back4App

In addition to string querying, you can also perform “exact” queries, when you want to retrieve objects that contain an exact value, just as with boolean fields. The next example will show how to retrieve users that are verified by email, through the emailVerified field.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const doUserQuery = async function () {
  // This value comes from a state variable
  const showOnlyVerifiedValue: boolean = showOnlyVerified;
  // This will create your user query
  const parseQuery = new Parse.Query(Parse.User);
  // Several query functions can be set to your Parse,Query, they will
  // only resolve when calling "find", for example
  if (showOnlyVerifiedValue === true) {
    // "equalTo" will retrieve users whose "emailVerified" value is exactly "true"
    parseQuery.equalTo('emailVerified', true);
  }
  // Only after calling "find" all query conditions will resolve
  return await parseQuery
    .find()
    .then(async (queriedUsers) => {
      // Set the query results to an state variable to retrieve it on your JSX
      // Be aware that empty or invalid queries return as an empty array
      setQueryResults(queriedUsers);
      return true;
    })
    .catch((error) => {
      // Error can be caused by lack of Internet connection, but in most
      // cases "find" will return as an empty array on "then"
      Alert.alert('Error!', error.message);
      setQueryResults([]);
      return false;
    });
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const doUserQuery = async function (): Promise<Boolean> {
  // This value comes from a state variable
  const showOnlyVerifiedValue: boolean = showOnlyVerified;
  // This will create your user query
  const parseQuery: Parse.Query = new Parse.Query(Parse.User);
  // Several query functions can be set to your Parse,Query, they will
  // only resolve when calling "find", for example
  if (showOnlyVerifiedValue === true) {
    // "equalTo" will retrieve users whose "emailVerified" value is exactly "true"
    parseQuery.equalTo('emailVerified', true);
  }
  // Only after calling "find" all query conditions will resolve
  return await parseQuery
    .find()
    .then(async (queriedUsers: [Parse.User]) => {
      // Set the query results to an state variable to retrieve it on your JSX
      // Be aware that empty or invalid queries return as an empty array
      setQueryResults(queriedUsers);
      return true;
    })
    .catch((error: object) => {
      // Error can be caused by lack of Internet connection, but in most
      // cases "find" will return as an empty array on "then"
      Alert.alert('Error!', error.message);
      setQueryResults([]);
      return false;
    });
};

Your app should now be updating your user list like this:

React Native Back4App

Another common example would be to apply orderings to your query. This can be done in two ways, either by using Parse.Query.ascending/Parse.Query.descending or Parse.Query.addAscending/Parse.Query.addDescending. The first case will override any other ordering and will be the only one that the query will take and the latter will concatenate with existing orderings, making multiple orderings possible.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const doUserQuery = async function () {
  // This value comes from a state variable
  const orderByValue = orderBy;
  // This will create your user query
  const parseQuery = new Parse.Query(Parse.User);
  // Several query functions can be set to your Parse,Query, they will
  // only resolve when calling "find", for example
  // For list ordering, you can use "addAscending" or "addDescending", passing as parameter
  // which object field should be the one to order by
  // Note that "usernameAsc", "usernameDesc" and so on are made up string values applied to a filter in
  // our example app, so change it by what is suitable to you
  if (orderByValue === 'usernameAsc') {
    parseQuery.ascending('username');
    //
    // or
    //
    parseQuery.addAscending('username');
  } else if (orderByValue === 'usernameDesc') {
    parseQuery.descending('username');
    //
    // or
    //
    parseQuery.addDescending('username');
  } else if (orderByValue === 'dateAsc') {
    parseQuery.ascending('createdAt');
    //
    // or
    //
    parseQuery.addAscending('createdAt');
  } else if (orderByValue === 'dateDesc') {
    parseQuery.descending('createdAt');
    //
    // or
    //
    parseQuery.addDescending('createdAt');
  }
  // Only after calling "find" all query conditions will resolve
  return await parseQuery
    .find()
    .then(async (queriedUsers) => {
      // Set the query results to an state variable to retrieve it on your JSX
      // Be aware that empty or invalid queries return as an empty array
      setQueryResults(queriedUsers);
      return true;
    })
    .catch((error) => {
      // Error can be caused by lack of Internet connection, but in most
      // cases "find" will return as an empty array on "then"
      Alert.alert('Error!', error.message);
      setQueryResults([]);
      return false;
    });
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const doUserQuery = async function (): Promise<Boolean> {
  // This value comes from a state variable
  const orderByValue: string = orderBy;
  // This will create your user query
  const parseQuery: Parse.Query = new Parse.Query(Parse.User);
  // Several query functions can be set to your Parse,Query, they will
  // only resolve when calling "find", for example
  // For list ordering, you can use "addAscending" or "addDescending", passing as parameter
  // which object field should be the one to order by
  // Note that "usernameAsc", "usernameDesc" and so on are made up string values applied to a filter in
  // our example app, so change it by what is suitable to you
  if (orderByValue === 'usernameAsc') {
    parseQuery.ascending('username');
    //
    // or
    //
    parseQuery.addAscending('username');
  } else if (orderByValue === 'usernameDesc') {
    parseQuery.descending('username');
    //
    // or
    //
    parseQuery.addDescending('username');
  } else if (orderByValue === 'dateAsc') {
    parseQuery.ascending('createdAt');
    //
    // or
    //
    parseQuery.addAscending('createdAt');
  } else if (orderByValue === 'dateDesc') {
    parseQuery.descending('createdAt');
    //
    // or
    //
    parseQuery.addDescending('createdAt');
  }
  // Only after calling "find" all query conditions will resolve
  return await parseQuery
    .find()
    .then(async (queriedUsers: [Parse.User]) => {
      // Set the query results to an state variable to retrieve it on your JSX
      // Be aware that empty or invalid queries return as an empty array
      setQueryResults(queriedUsers);
      return true;
    })
    .catch((error: object) => {
      // Error can be caused by lack of Internet connection, but in most
      // cases "find" will return as an empty array on "then"
      Alert.alert('Error!', error.message);
      setQueryResults([]);
      return false;
    });
};

Your app must now be ordering your queries like this:

React Native Back4App

Remember that all of the query constraints mentioned above can be chained and performed in a single query, improving your app usability for creating different filters and orderings that will work altogether. Here is the full code presenting all the query methods used in this guide:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
const doUserQuery = async function () {
  // This value comes from a state variable
  const usernameSearchValue = usernameSearch;
  const showOnlyVerifiedValue = showOnlyVerified;
  const orderByValue = orderBy;
  // This will create your user query
  const parseQuery = new Parse.Query(Parse.User);
  // Several query functions can be set to your Parse,Query, they will
  // only resolve when calling "find", for example
  if (usernameSearchValue !== '') {
    // "contains" will retrieve users whose username contain the searched value, case-sensitive
    parseQuery.contains('username', usernameSearchValue);
    //
    // or
    //
    // for case-insensitive string search, use "matches", that will take into account
    // an regexp for matching, in this case use only "i", which is the regexp modifier
    // for case-insensitive
    parseQuery.matches('username', usernameSearchValue, 'i');
  }
  if (showOnlyVerifiedValue === true) {
    // "equalTo" will retrieve users whose "emailVerified" value is exactly "true"
    parseQuery.equalTo('emailVerified', true);
  }
  // For list ordering, you can use "addAscending" or "addDescending", passing as parameter
  // which object field should be the one to order by
  if (orderByValue === 'usernameAsc') {
    parseQuery.ascending('username');
    //
    // or
    //
    parseQuery.addAscending('username');
  } else if (orderByValue === 'usernameDesc') {
    parseQuery.descending('username');
    //
    // or
    //
    parseQuery.addDescending('username');
  } else if (orderByValue === 'dateAsc') {
    parseQuery.ascending('createdAt');
    //
    // or
    //
    parseQuery.addAscending('createdAt');
  } else if (orderByValue === 'dateDesc') {
    parseQuery.descending('createdAt');
    //
    // or
    //
    parseQuery.addDescending('createdAt');
  }
  // Only after calling "find" all query conditions will resolve
  return await parseQuery
    .find()
    .then(async (queriedUsers) => {
      // Set the query results to an state variable to retrieve it on your JSX
      // Be aware that empty or invalid queries return as an empty array
      setQueryResults(queriedUsers);
      return true;
    })
    .catch((error) => {
      // Error can be caused by lack of Internet connection, but in most
      // cases "find" will return as an empty array on "then"
      Alert.alert('Error!', error.message);
      setQueryResults([]);
      return false;
    });
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
const doUserQuery = async function (): Promise<Boolean> {
  // This value comes from a state variable
  const usernameSearchValue: string = usernameSearch;
  const showOnlyVerifiedValue: boolean = showOnlyVerified;
  const orderByValue: string = orderBy;
  // This will create your user query
  const parseQuery: Parse.Query = new Parse.Query(Parse.User);
  // Several query functions can be set to your Parse,Query, they will
  // only resolve when calling "find", for example
  if (usernameSearchValue !== '') {
    // "contains" will retrieve users whose username contain the searched value, case-sensitive
    parseQuery.contains('username', usernameSearchValue);
    //
    // or
    //
    // for case-insensitive string search, use "matches", that will take into account
    // an regexp for matching, in this case use only "i", which is the regexp modifier
    // for case-insensitive
    parseQuery.matches('username', usernameSearchValue, 'i');
  }
  if (showOnlyVerifiedValue === true) {
    // "equalTo" will retrieve users whose "emailVerified" value is exactly "true"
    parseQuery.equalTo('emailVerified', true);
  }
  // For list ordering, you can use "addAscending" or "addDescending", passing as parameter
  // which object field should be the one to order by
  if (orderByValue === 'usernameAsc') {
    parseQuery.ascending('username');
    //
    // or
    //
    parseQuery.addAscending('username');
  } else if (orderByValue === 'usernameDesc') {
    parseQuery.descending('username');
    //
    // or
    //
    parseQuery.addDescending('username');
  } else if (orderByValue === 'dateAsc') {
    parseQuery.ascending('createdAt');
    //
    // or
    //
    parseQuery.addAscending('createdAt');
  } else if (orderByValue === 'dateDesc') {
    parseQuery.descending('createdAt');
    //
    // or
    //
    parseQuery.addDescending('createdAt');
  }
  // Only after calling "find" all query conditions will resolve
  return await parseQuery
    .find()
    .then(async (queriedUsers: [Parse.User]) => {
      // Set the query results to an state variable to retrieve it on your JSX
      // Be aware that empty or invalid queries return as an empty array
      setQueryResults(queriedUsers);
      return true;
    })
    .catch((error: object) => {
      // Error can be caused by lack of Internet connection, but in most
      // cases "find" will return as an empty array on "then"
      Alert.alert('Error!', error.message);
      setQueryResults([]);
      return false;
    });
};

Conclusion

At the end of this guide, you learned how to perform queries on Parse users on React Native. In the next guide, we will show you how to save and read data on Parse.