parse_connect 0.0.9

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 74

parse_connect package for Flutter #

Parse_Connect is a package that provides Parse client functionality for Flutter. It is currently based on , and developed against, a Parse server setup on Back4App. This first release is limited and provides basic functionality for:

  • Object
  • User
  • Function

With it you should be able to create, edit, update and delete Objects as well as signing up, updating, deleting and logging on Users. And with the 0.0.9 update also call a cloud function.

This is currently Work in Progress and the API's are subject to updates and modifications as they are developed and refined.

Updates #

0.0.9 #

Added the ability to execute cloud functions. This is simply done using api.function({functionName}).execute({params to pass function}). There is shown in the example app.

0.0.8 #

Updated the user validate() method to automatically set the sessionToken if it is valid

0.0.7 #

Modified login & logout to automatically track the user sessionToken.

0.0.6 #

This update fixes an issue that manifested itself when logging different users in and out on the same device. As the headers Map was final each call added to the header params which meant when logging in, then out, then in as a different user the old sessionToken remained and caused an Invalid SessionToken error.

Each base call now uses a master copy of the headers map so only the basic headers and the additional ones required for the specific call are passed.

0.0.5 #

This now has 2 additional methods added to the User object

  • validate(sessionToken)
  • logout(sessionToken)

Example Usage #

As I eat my own dog food (never did like that phrase, but it kinda fits) I will put some code snippets on the project Wiki here.

Getting Started #

For package install see here.

For help getting started with Flutter, view the online documentation.

[0.0.9] - 29 Nov 2018

  • added the ability to run a cloud function

[0.0.8] - 20 Nov 2018

  • update user validate() to set API session token if valid

[0.0.7] - 20 Nov 2018

  • Update User login & logout to track user sessionToken plus some documentation updates

[0.0.6] - 20 Nov 2018

  • Corrected issues with header values in baseObject

[0.0.5] - 17 Nov 2018

  • Add logout functionality

[0.0.4] - 11 Nov 2018

  • Add User verification using session token

[0.0.3] - 08 Nov 2018.

  • Updated dependency on http for flutter sdk release 0.10.2.

[0.0.2] - 05 Nov 2018.

  • Documentation updates only.

[0.0.1] - 03 Nov 2018.

  • Initial release with limited Object and User functionality.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:parse_connect/parse_connect.dart' as ParseConnect;

void main() => runApp(ParseDemo());

class ParseDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: 'ParseDemo', home: DemoScreen());
  }
}

/// Simple Demo of using Parse_Connect to connect  a Flutter app to a Parse Server
/// This demo and the Package where developed and tested again  a server on the
/// https://www.back4app.com/  service and has not be tested again other Parse services
///
class DemoScreen extends StatefulWidget {
  @override
  _DemoScreenState createState() => _DemoScreenState();
}

class _DemoScreenState extends State<DemoScreen> {
  ParseConnect.ParseAPI api = ParseConnect.ParseAPI(
      "https://parseapi.back4app.com",
      "{put_your_app_id_here}",
      "{put_your-REST-api_key_here}");
  @override
  initState() {
    super.initState();
    api.debug = true; // for testing lets print out some debug messages
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Back4App Parse Demo"),
      ),
      body: ListView(
        children: <Widget>[
          RaisedButton(
            onPressed: () async {
              // Test Object Interface
              //_testObjectInterface("MyTestObject");

              // Test User interface
              //_testUserInterface();

              // Test the cloud function interface
              _testCloudFunctionInterface();
            },
            child: Text("Run Parse Test"),
          ),
        ],
      ),
    );
  }

  // simple example of executing a cloud function
  _testCloudFunctionInterface() async {
    ParseConnect.ParseResult result;

    Map params = {"firstName": "Fred", "lastName": "Flintstone"};
    result = await api.function("test").execute(params);
    print(result.ok);
    print(result.data);
  }

  // This is an example of the User interface
  // This will run Create, Query, Login, Read, Update,
  _testUserInterface() async {
    ParseConnect.ParseResult result;
    String userId, sessionToken;

/*
    // CREATE a user object (user "FRED")
    print("CREATE USER: fred --------------------------------");
    result = await api
        .user()
        .create({"username": "fred", "password": "password"});
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    }

    // Verify the user with the returned session token
    print("VERIFY USER: fred --------------------------------");
    sessionToken = result.data['sessionToken'];
    result = await api.user().validate(sessionToken);
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    } else {
      print(result.data);
    }

    //  Log user out
    print("LOGOUT USER: fred --------------------------------");
    result = await api.user().logout();
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    } else {
      print(result.data);
    }



    // CREATE a user object (user "WILMA")
    print("CREATE USER: wilma --------------------------------");
    result = await api
        .user()
        .create({"username": "wilma", "password": "password"});
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    }

    // Verify the user with the returned session token
    print("VERIFY USER: wilma --------------------------------");
    sessionToken = result.data['sessionToken'];
    result = await api.user().validate(sessionToken);
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    } else {
      print(result.data);
    }

    //  Log user out
    print("LOGOUT USER: wilma --------------------------------");
    result = await api.user().logout();
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    } else {
      print(result.data);
    }

    // Log in Fred
    print("LOGIN USER: fred --------------------------------");
    result = await api.user().login("fred", "password");
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    userId = result.data['objectId'];

    // Add an object
    print("ADD OBJECT FOR: fred --------------------------------");    
    result = await api.object("BedRock").create({
      "Name": "This is Fred's Object",
      "ACL": {
		    userId: {
			    "read": true,
			    "write": true
		    }
	    }
    });
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);

    //  Log fred out
    print("LOGOUT USER: fred --------------------------------");
    result = await api.user().logout();
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    } else {
      print(result.data);
    }

    // Log in Wilma
    print("LOGIN USER: wilma --------------------------------");
    result = await api.user().login("wilma", "password");
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    userId = result.data['objectId'];
    // Add an object
    print("ADD OBJECT FOR: wilma --------------------------------");    
    result = await api.object("BedRock").create({
      "Name": "This is Wilma's Object",
      "ACL": {
		    userId: {
			    "read": true,
			    "write": true
		    }
	    }  
    });
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);

    //  Log wilma out
    print("LOGOUT USER: wilma --------------------------------");
    result = await api.user().logout();
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    } else {
      print(result.data);
    }


    // Log in Fred
    print("LOGIN USER: fred --------------------------------");
    result = await api.user().login("fred", "password");
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    userId = result.data['objectId'];

    // Query for ALL fred's object
    print("QUERY objects: fred --------------------------------");    
    result = await api.object("BedRock").query();
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);

    //  Log fred out
    print("LOGOUT USER: fred --------------------------------");
    result = await api.user().logout();
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    } else {
      print(result.data);
    }

    // Log in Wilma
    print("LOGIN USER: fred --------------------------------");
    result = await api.user().login("wilma", "password");
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    userId = result.data['objectId'];

    // Query for ALL Wilma's object
    print("QUERY objects: wilma --------------------------------");    
    result = await api.object("BedRock").query();
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);

    //  Log wilma out
    print("LOGOUT USER: wilma --------------------------------");
    result = await api.user().logout();
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    } else {
      print(result.data);
    }

  */

    /*
    // Query to see if an account exists already
    result = await api.user().query(where: '{"email": "$email"}');
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);

    // Send an Email Verification Request
    result = await api.user().verifyEmail(email);
    if(!result.ok){
     throw("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);
   */

    // CREATE a user object
    result =
        await api.user().create({"username": "barney", "password": "password"});
    if (!result.ok) {
      print("${result.errorCode}:${result.errorMessage}");
    }

    // LOGIN user
    result = await api.user().login("barney", "password");
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    userId = result.data['objectId'];

    // get user details
    print("Test READ()");
    result = await api.user(userId).read();
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);

    // Test UPDATE user
    result = await api
        .user(userId)
        .update({"jobtitle": "Fred's sidekick and father to Pebbles"});
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);

    /// DELETE the test user object
    result = await api.user(userId).delete();
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);

    /*
    // Test Password Reset Request
    result = await api.user().passwordReset(email);
    if(!result.ok){
     throw("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);
    */
  }

  /// This is an example of the calls that can be made again a custom Parse object
  // The methods will be run in the order of Create, Query, Update, Read, Delete
  _testObjectInterface(String objectClassName) async {
    ParseConnect.ParseResult result;
    String objectID;

    // CREATE a test object
    result =
        await api.object(objectClassName).create({"Name": "Around the Lake"});
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);
    objectID = result.data['objectId'];

    // QUERY ALL OBJECTS
    result = await api.object(objectClassName).query();
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);

    // UPDATE created object
    result = await api
        .object(objectClassName)
        .update(objectID, {"vehicle": "Motorbike"});

    // READ updated object
    result = await api.object(objectClassName).read(objectID);
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);

    // DELETE the created objet
    result = await api.object(objectClassName).delete(objectID);
    if (!result.ok) {
      throw ("${result.errorCode}:${result.errorMessage}");
    }
    print(result.data);
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  parse_connect: ^0.0.9

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:parse_connect/parse_connect.dart';
  
Version Uploaded Documentation Archive
0.0.9 Nov 29, 2018 Go to the documentation of parse_connect 0.0.9 Download parse_connect 0.0.9 archive
0.0.8 Nov 20, 2018 Go to the documentation of parse_connect 0.0.8 Download parse_connect 0.0.8 archive
0.0.7 Nov 20, 2018 Go to the documentation of parse_connect 0.0.7 Download parse_connect 0.0.7 archive
0.0.6 Nov 20, 2018 Go to the documentation of parse_connect 0.0.6 Download parse_connect 0.0.6 archive
0.0.5 Nov 17, 2018 Go to the documentation of parse_connect 0.0.5 Download parse_connect 0.0.5 archive
0.0.4 Nov 11, 2018 Go to the documentation of parse_connect 0.0.4 Download parse_connect 0.0.4 archive
0.0.3 Nov 8, 2018 Go to the documentation of parse_connect 0.0.3 Download parse_connect 0.0.3 archive
0.0.2 Nov 5, 2018 Go to the documentation of parse_connect 0.0.2 Download parse_connect 0.0.2 archive
0.0.1 Nov 3, 2018 Go to the documentation of parse_connect 0.0.1 Download parse_connect 0.0.1 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
52
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
90
Overall:
Weighted score of the above. [more]
74
Learn more about scoring.

We analyzed this package on Mar 6, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.2.0
  • pana: 0.12.14
  • Flutter: 1.3.3

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Maintenance suggestions

Package is pre-v0.1 release. (-10 points)

While nothing is inherently wrong with versions of 0.0.*, it might mean that the author is still experimenting with the general direction of the API.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.68.0 <3.0.0
flutter 0.0.0
http >=0.11.3+17 <1.0.0 0.12.0+1
Transitive dependencies
async 2.0.8
charcode 1.1.2
collection 1.14.11
http_parser 3.1.3
meta 1.1.6 1.1.7
path 1.6.2
sky_engine 0.0.99
source_span 1.5.5
string_scanner 1.0.4
term_glyph 1.1.0
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test