Flutter

Querying users in Parse on Flutter

Introduction

Some applications need to directly manage users or be able to view a list of them. Parse has query tools and they can be used to list the users of your application.

In this guide, you will learn how to use ParseQuery to perform user queries in your Flutter application using the Flutter plugin for Parse Server.

Goal

To build a user querying feature using Parse for a Flutter App.

Prerequisites

To complete this tutorial, you will need:

Understanding the Query Users App

To better understand the Query Users process, we will create an app to query. We won’t explain the Flutter application code once this guide’s primary focus is using the Flutter with Parse.

Following the next steps, you will build a Todo App that will store the tasks at Back4App Database.

Let’s get started!

Following the next steps you will be able to build a Sign App that will create user Account in Back4App Database.

Step 1 - Create Query Users App Template

Open your Flutter project from the previous guide Flutter plugin for Parse Server. Go to the main.dart file, clean up all the code, and replace it with:

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  final keyApplicationId = 'YOUR_APP_ID_HERE';
  final keyClientKey = 'YOUR_CLIENT_KEY_HERE';
  final keyParseServerUrl = 'https://parseapi.back4app.com';

  await Parse().initialize(keyApplicationId, keyParseServerUrl,
      clientKey: keyClientKey, debug: true);

  runApp(MaterialApp(
    home: Home(),
  ));
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Parse Query Users"),
          backgroundColor: Colors.blueAccent,
          centerTitle: true,
        ),
        key: _scaffoldKey,
        body: FutureBuilder<List<ParseObject>>(
            future: doUserQuery(),
            builder: (context, snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                case ConnectionState.waiting:
                  return Center(
                    child: Container(
                        width: 100,
                        height: 100,
                        child: CircularProgressIndicator()),
                  );
                default:
                  if (snapshot.hasError) {
                    return Center(
                      child: Text("Error...: ${snapshot.error.toString()}"),
                    );
                  } else {
                    if (snapshot.data!.isEmpty) {
                      return Center(
                        child: Text('None user found'),
                      );
                    }

                    return ListView.builder(
                        padding: EdgeInsets.only(top: 10.0),
                        itemCount: snapshot.data!.length,
                        itemBuilder: (context, index) {
                          final user = snapshot.data![index] as ParseUser;
                          final userVerified = user.emailVerified ?? false;
                          return ListTile(
                            title: Text(
                                'Username: ${user.username} - Verified: ${userVerified.toString()}'),
                            subtitle: Text(user.createdAt.toString()),
                          );
                        });
                  }
              }
            }));
  }

  Future<List<ParseObject>> doUserQuery() async {
    return [];
  }
}

When debug parameter in function Parse().initialize is true, allows displaying Parse API calls on the console. This configuration can assist in debugging the code. It is advisable to disable debug in the release version.

Step 2 - Connect Template to Back4app Project

Find your Application Id and Client Key credentials navigating to your app Dashboard at Back4App Website.

Update your code in main.dart with the values of your project’s ApplicationId and ClientKey in Back4app.

  • keyApplicationId = App Id
  • keyClientKey = Client Key

Run the project, and the app will load as shown in the image.

flutter-query-users

Step 3 - Code for Query Users

Any Parse query operation uses the ParseQuery object type, which will help you retrieve specific data from your database throughout your app.

A ParseQuery will only resolve after calling a retrieve method, so you can set up a query and chain its several modifiers before submitting the retrieve method.

To create a new ParseQuery, you need to pass as a parameter the desired ParseObject subclass, which is the one that will contain your query results.

You can see a user query example below. Using the code provided, find the doUserQuery function in the file main.dart. Replace the code inside doUserQuery with:

1
2
3
4
5
6
7
8
9
    QueryBuilder<ParseUser> queryUsers =
        QueryBuilder<ParseUser>(ParseUser.forQuery());
    final ParseResponse apiResponse = await queryUsers.query();

    if (apiResponse.success && apiResponse.results != null) {
      return apiResponse.results as List<ParseObject>;
    } else {
      return [];
    }

To build this function, follow these steps:

  1. Create an instance of ParseQuery class e pass as a parameter to the ParseUser.forQuery
  2. Call the query function that will execute the query against the database.
  3. If the operations succeed, will return a list of ParseUser objects. If the operation does not find any objects, the success property will be false, and the results are null.

The complete code should look like this:

1
2
3
4
5
6
7
8
9
10
11
  Future<List<ParseObject>> doUserQuery() async {
    QueryBuilder<ParseUser> queryUsers =
        QueryBuilder<ParseUser>(ParseUser.forQuery());
    final ParseResponse apiResponse = await queryUsers.query();

    if (apiResponse.success && apiResponse.results != null) {
      return apiResponse.results as List<ParseObject>;
    } else {
      return [];
    }
  }

You can also try to retrieve a single user using the following structure:

  user?.get("username");

To test it, click on the Run button in Android Studio/VSCode.

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

flutter-user-query-1.png

It’s done!

At the end of this guide, you learned how to perform queries on Parse users on Flutter.