appstrax_services 0.1.0
appstrax_services: ^0.1.0 copied to clipboard
A library to integrate with Appstrax Services, an authentication, database and file storage service.
Table of Contents #
- Overview
- Getting Started
- Installation
- Setup
- Auth Service
- User Service
- Database Service
- Storage Service
Overview #
Appstrax in partnership with CodeCapsules provides software tools and infrastructure to assist in the development, hosting and managing of your applications.
Getting Started #
To use the available services, an instance of the Auth, Database and Storage API need to be configured internally.
Each instance deploys a front-end to interact with registered users, application data and uploaded Files accordingly.
To get this instance set-up, first send an email to info@appstrax.tech and we'll help create, host and manage your Appstrax API here: https://codecapsules.io/
Installation #
Add appstrax_services
as a project dependency:
pub get appstrax_services
Setup #
Initialize the appstrax_services
libraries:
// import the services library
import 'package:appstrax_services/initialize.dart';
// initialize the service
await initializeAppstraxServices(
apiUrl: 'https://<your-appstrax-services-instance>',
apiKey: '<your-appstrax-services-instance-api-key>',
);
Auth Service #
This library integrates with the Appstrax Auth API which allows you to easily interact with authentication in your mobile applications.
To get started import appstraxAuth
into your project:
import 'package:appstrax_services/auth.dart';
Registration #
RegisterDto registerDto = RegisterDto(
email: 'joe@soap.com',
password: '<password>',
data: {
// any additional/custom user fields
'name': 'Joe',
'surname': 'Soap',
...
}
);
try {
AuthResult result = await appstraxAuth.register(registerDto);
User user = result.user!;
print('User Successfully Registered, userId: ${user.id}');
} catch (err) {
// something went wrong while registering the user
handleError(err);
}
Login #
LoginDto loginDto = LoginDto(
email: 'email',
password: '<password>',
);
try {
AuthResult result = await appstraxAuth.login(loginDto);
User user = result.user!;
print('User Successfully Logged In, userId: ${user.id}');
} catch (err) {
// something went wrong while logging in
handleError(err);
}
Forgot Password #
ForgotPasswordDto forgotPasswordDto = ForgotPasswordDto(
email: 'email'
);
try {
Message message = await appstraxAuth.forgotPassword(forgotPasswordDto);
print('forgotPassword email sent: ${message.message}');
} catch (err) {
// something went wrong sending the email
handleError(err);
}
An email will be sent to the user with a password reset code, this code is only valid for 24 hours.
Reset Password #
ResetPasswordDto resetPasswordDto = ResetPasswordDto(
email: 'email',
code: '<code>',
password: '<password>',
);
try {
Message message = await appstraxAuth.resetPassword(resetPasswordDto);
print('Password Successfully Reset: ${message.message}');
} catch (err) {
// something went wrong while resetting the password
handleError(err);
}
The password is now reset, however the user will now need to login with their new password.
Change Password #
ChangePasswordDto changePasswordDto = ChangePasswordDto(
password: '<currentPassword>',
newPassword: '<newPassword>',
);
try {
User user = await appstraxAuth.changePassword(changePasswordDto);
print('Changed password for userId: ${user.id}');
} catch (err) {
// something went wrong while changing the password
handleError(err);
}
Users can only change their password if they are already authenticated.
Save User Data/Profile #
try {
User updatedUser = await appstraxAuth.saveUserData({
// any additional/custom user fields
'name': 'Joe',
'surname': 'Soap',
'career': 'Software Engineer',
...
});
print('user data successfully updated, userId: ${updatedUser.id}');
} catch (err) {
// something went wrong while updating the user data
handleError(err);
}
Users can only update their data if they are already authenticated.
Logout #
try {
await appstraxAuth.logout():
} catch (err) {
// something went wrong while logging out
handleError(err);
}
Auth Error Messages #
class AuthErrors {
// registration errors
static const emailAddressAlreadyExists = 'emailAddressAlreadyExists';
static const badlyFormattedEmailAddress = 'badlyFormattedEmailAddress';
static const noPasswordSupplied = 'noPasswordSupplied';
// login errors
static const invalidEmailOrPassword = 'invalidEmailOrPassword';
static const userBlocked = 'userBlocked';
static const invalidTwoFactorAuthCode = 'invalidTwoFactorAuthCode';
// forgot/reset password errors
static const emailAddressDoesNotExist = 'emailAddressDoesNotExist';
static const invalidResetCode = 'invalidResetCode';
// unknown errors
static const unexpectedError = 'unexpectedError';
}
User Service #
This library integrates with the Appstrax Auth API which allows you to easily manage the users in your mobile applications.
To get started import appstraxUsers
into your project:
import 'package:appstrax_services/auth.dart';
Public Availability #
Admin Panel -> Configuration tab -> Public Access -> toggle 'Allow Public Access'
Querying Users #
The appstraxUsers.find()
function takes a FetchQuery as an argument and returns a FindResultDto
Examples #
A query to search for the users
table similar to:
SELECT * FROM users WHERE email LIKE '%Joe%' ORDER BY email ASC LIMIT 5
FetchQuery query = FetchQuery(
// where: {"email":{"LIKE":"Joe"}}
where: { email: { Operator.LIKE: 'Joe' } },
// order: {"email": "ASC"}
order: {},
offset: 0,
limit: 5,
);
try {
FindResult users = await appstraxUsers.find(query: query);
totalUsers = users.count;
userData = users.data;
} catch (err) {
// something went wrong while querying the users
handleError(err);
}
A query to search for the users
table similar to:
SELECT * FROM users WHERE email LIKE '%Joe%' OR name LIKE '%Joe%' OR surname LIKE '%Joe%' LIMIT 5
FetchQuery query = FetchQuery(
// where: {"OR":[{"email":{"LIKE":"cam"}},{"name":{"LIKE":"cam"}},{"surname":{"LIKE":"cam"}}]}
where: {
Operator.OR: [
{ email: { Operator.LIKE: 'Joe' } },
{ name: { Operator.LIKE: 'Joe' } },
{ surname: { Operator.LIKE: 'Joe' } },
],
},
// order: {"email":"ASC"}
order: {"email": OrderDirection.ASC},
offset: 0,
limit: 5,
);
try {
FindResult users = await appstraxUsers.find(query: query);
totalUsers = users.count;
userData = users.data;
} catch (err) {
// something went wrong while querying the users
handleError(err);
}
try {
User user = await appstraxUsers.findById(id);
} catch (err) {
// something went wrong while querying the users
handleError(err);
}
try {
User user = await appstraxUsers.findByEmail(email);
} catch (err) {
// something went wrong while querying the users
handleError(err);
}
Database Service #
This library integrates with the Appstrax Database API which allows you to easily interact with your database in your mobile applications.
To get started import appstraxDb
into your project:
import 'package:appstrax_services/database.dart';
Create #
// Create a new Document, returns a DocumentDto from the 'testing' collection
try {
var document = await appstraxDb.create('testing', {
'name': 'John',
'surname': 'Doe',
'dogs': 3,
'career': 'Software Engineer',
});
createdId = document.id;
print('Document created docId: $createdId');
} catch (err) {
// something went wrong while creating
handleError(err);
}
Edit #
// edit documents
try {
var document = await appstraxDb.edit('testing', createdId, {
'name': 'John',
'surname': 'Doe',
'dogs': 3,
'career': 'Senior Software Engineer',
'added': 'this field'
});
print('Document edited: ${document.id}');
} catch (err) {
// something went wrong while editing
handleError(err);
}
Delete #
// delete documents
try {
await appstraxDb.delete('testing', createdId as String);
print('Document deleted.');
} catch (err) {
// something went wrong while deleting
handleError(err);
}
Find By Id #
// findById returns a DocumentDto from the 'testing' collection
try {
var document = await appstraxDb.findById('testing', createdId as String);
print('Document foundById: ${document.id}');
} catch (err) {
// something went wrong while querying the 'testing' collection
handleError(err);
}
Find #
// find returns a FindResultDto<DocumentDto>
try {
var documents = await appstraxDb.find('testing');
if (documents.data?.length != null) {
documents.data?.forEach((user) {
print('docId: ${user.id}');
});
}
} catch (err) {
// something went wrong while querying the 'testing' collection
handleError(err);
}
// find accepts a FetchQuery as in examples above
// You can create compound queries
// Here we search for documents where name=='John' AND dogs IN [1, 5, 7, 2]
try {
FindResultDto<DocumentDto> documents = await appstraxDb.find(
'testing',
query: FetchQuery(
where: {
Operator.and: [
{
'name': {Operator.equal: 'John'}
},
{
'dogs': {
Operator.qIn: [1, 5, 7, 2]
}
},
]
},
order: {"email": OrderDirection.ASC},
offset: 0,
limit: 5,
),
);
if (documents.data?.length != null) {
documents.data?.forEach((user) {
print('docId: ${user.id}');
});
}
print('Documents found using find(query)');
} catch (err) {
// something went wrong while querying the 'testing' collection
handleError(err);
}
CRUD Service #
The CrudService
is a abstract class which wraps the Create, Read, Update and Delete functions in appstraxDb
. The CrudService
is declared with a model which extends the Model
class, this model is the type that the service Creates, Reads, Updates and Deletes.
Similarly to appstraxDb
, the CrudService
uses a collection name which represents the "table" that the data is stored in on the server.
To get started import CrudService & Model
into your project:
import 'package:appstrax_services/database.dart';
Create your custom Model & Service
:
// Create a custom Model that implements the base Model
import 'package:json_annotation/json_annotation.dart';
import 'package:appstrax_services/shared/models/model.dart';
part 'person.g.dart';
@JsonSerializable()
class Person implements Model {
@override
String? id;
@override
DateTime? createdAt;
@override
DateTime? updatedAt;
String name;
String surname;
String career;
int dogs;
Person({
this.id,
this.createdAt,
this.updatedAt,
required this.name,
required this.surname,
required this.career,
required this.dogs,
});
factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);
@override
Map<String, dynamic> toJson() => _$PersonToJson(this);
}
// Generate your person.g.dart file from the terminal with:
flutter pub run build_runner build
// Create a custom service for the Model that extends the CRUD service
class PersonService extends CrudService<Person> {
PersonService() : super('person', Person.fromJson);
}
var personService = PersonService();
We can now use the ProfileService
as follows:
// Now you have access to all the CRUD functions on your personService
try {
Person person = Person(
name: 'James',
surname: 'Doe',
career: 'farmer',
dogs: 9,
);
// save checks for an ID, if it exists the doc is edited else it is created
var createdPerson = await personService.save(person);
personCreatedId = createdPerson.id;
print('Person created: ${createdPerson.id}');
} catch (err) {
// something went wrong while saving
handleError(err);
}
// The CRUD service returns the type created ie: Person
try {
var foundPerson = await personService.findById(personCreatedId as String);
print('Person foundById: ${foundPerson.id}');
} catch (err) {
// something went wrong while querying
handleError(err);
}
// find
try {
var foundPersons = await personService.find();
if (foundPersons != null) {
for (var per in foundPersons) {
print('DocId: ${per.id}');
}
}
} catch (err) {
// something went wrong while querying
handleError(err);
}
// The find() accepts a FetchQuery, same as above
try {
var foundPersons = await personService.find(
query: FetchQuery(where: {
'name': {Operator.equal: 'James'}
}),
);
if (foundPersons != null) {
for (var per in foundPersons) {
print('DocId: ${per.id}');
}
}
} catch (err) {
// something went wrong while querying
handleError(err);
}
Storage Service #
This library integrates with the Appstrax Storage API which allows you to easily interact with storage in your mobile applications.
To get started import appstraxStorage
into your project:
import 'package:appstrax_services/storage.dart';
Examples #
// Upload File
try {
Response res = await appstraxStorage.uploadFile(file, '<folder>/',
options: HttpOptions(
onUploadProgress: (progress) => print(
'Upload Progress: ${progress.percent}',
),
));
downloadUrl = res.downloadUrl;
print('DownloadUrl: ${res.downloadUrl}');
} catch (err) {
// something went wrong while uploading
handleError(err);
}
// Delete File using downloadUrl
try {
await appstraxStorage.deleteFile(downloadUrl as String);
print('Deleted successfully');
} catch (err) {
// something went wrong while deleting
handleError(err);
}
Query Models #
The find()
function accepts FetchQuery
as an argument:
Fetch Query #
class FetchQuery {
// Conditions to query data
Map<String, dynamic>? where;
// ASC, DESC Order
Map<String, dynamic>? order;
// Pagination variables
int? offset;
int? limit;
}
class OrderDirection {
// Ascending Order Direction
static const asc = 'ASC';
// Descending Order Direction
static const desc = 'DESC';
}
Query Operators #
class Operator {
// Equal To Operator
static const String equal = 'EQUAL';
// Not Equal To Operator
static const String notEqual = 'EQUAL';
// And Operator
static const String and = 'AND';
// Or Operator
static const String or = 'OR';
// Greater Than Operator
static const String gt = 'GT';
// Greater Than or Equal To Operator
static const String gte = 'GTE';
// Less Than Operator
static const String lt = 'LT';
// Less Than or Equal To Operator
static const String lte = 'LTE';
// Like Operator
static const String like = 'LIKE';
// Not Like Operator
static const String notLike = 'NOT_LIKE';
// In Operator
static const String qIn = 'IN';
}
Query Results #
The find()
function returns a FindResultDto
:
// querying the data returns a FindResultDto<DocumentDto> from the collection
class FindResultDto<T extends DocumentDto> {
List<DocumentDto>? data;
dynamic where;
dynamic order;
int? limit;
int? offset;
int? count;
FindResultDto({
this.data,
this.where,
this.order,
this.limit,
this.offset,
this.count,
});
}
class DocumentDto {
final String id;
final Map<String, dynamic> data;
final DateTime createdAt;
final DateTime updatedAt;
DocumentDto(
this.id,
this.data,
this.createdAt,
this.updatedAt,
);
}