parse_connect 0.0.7

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

With it you should be able to create, edit, update and delete Objects as well as signing up, updating, deleting and logging on Users.

release 0.0.7 #

Modified login & logout to automatically track the user sessionToken.

release 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.

release 0.0.5 #

This now has 2 additional methods added to the User object

  • validate(sessionToken)
  • logout(sessionToken)

This is currently Work in Progress.

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.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 Parser 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();
            },
            child: Text("Run Parse Test"),
          ),
        ],
      ),
    );
  }

  // 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.7

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub 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';
  
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 Sep 11, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.5.0
  • pana: 0.12.21
  • Flutter: 1.9.1+hotfix.2

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Health suggestions

Fix lib/src/user.dart. (-0.50 points)

Analysis of lib/src/user.dart reported 1 hint:

line 64 col 7: Avoid empty statements.

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+2
Transitive dependencies
async 2.3.0
charcode 1.1.2
collection 1.14.11 1.14.12
http_parser 3.1.3
meta 1.1.7
path 1.6.4
pedantic 1.8.0+1
sky_engine 0.0.99
source_span 1.5.5
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test