Sunteți pe pagina 1din 112

2014 Backendless Corp.

Backendless API for JavaScript


All rights reserved. No parts of this work may be reproduced in any form or by any means - graphic, electronic, or
mechanical, including photocopying, recording, taping, or information storage and retrieval systems - without the
written permission of the publisher.
Products that are referred to in this document may be either trademarks and/or registered trademarks of the
respective owners. The publisher and the author make no claim to these trademarks.
While every precaution has been taken in the preparation of this document, the publisher and the author assume no
responsibility for errors or omissions, or for damages resulting from the use of information contained in this
document or from the use of programs and source code that may accompany it. In no event shall the publisher and
the author be liable for any loss of profit or any other commercial damage caused or alleged to have been caused
directly or indirectly by this document.
Generated on: May 2014
Backendless API for JavaScript
2014 Backendless Corp.
All the people who contributed to this document, to everyone who
has helped us out with the vision for the product, feature
suggestions and ideas for improvements. Special thanks to our
families for your support, encouragement and patience.
Special thanks to:
3
Contents
3
2014 Backendless Corp.
Table of Contents
User Service
5
................................................................................................................................... 5 1 Overview
................................................................................................................................... 5 2 Setup
................................................................................................................................... 6 3 Core Classes
................................................................................................................................... 7 4 Error Handling
................................................................................................................................... 7 5 User Properties
................................................................................................................................... 9 6 Retrieve User Entity Properties
................................................................................................................................... 10 7 User Registration
................................................................................................................................... 13 8 Login
................................................................................................................................... 17 9 Update User Properties
................................................................................................................................... 19 10 Get Current User
................................................................................................................................... 19 11 Logout
................................................................................................................................... 21 12 Password Recovery
................................................................................................................................... 22 13 Security
................................................................................................................................... 27 14 Role to User Mapping
Data Service
28
................................................................................................................................... 28 1 Overview
................................................................................................................................... 29 2 Setup
................................................................................................................................... 30 3 Sync and Async Calls
................................................................................................................................... 30 4 Error Handling
................................................................................................................................... 31 5 Data Object
................................................................................................................................... 31 6 Saving Data Objects
................................................................................................................................... 32 7 Updating Data Objects
................................................................................................................................... 33 8 Deleting Data Objects
................................................................................................................................... 34 9 Basic Search
................................................................................................................................... 36 10 Advanced Search
................................................................................................................................... 38 11 Related Data
................................................................................................................................... 47 12 Security
Messaging Service
52
................................................................................................................................... 52 1 Overview
................................................................................................................................... 53 2 Setup
................................................................................................................................... 54 3 Core Classes
................................................................................................................................... 56 4 Sync and Async Calls
Backendless API for JavaScript
2014 Backendless Corp.
4
................................................................................................................................... 56 5 Error Handling
................................................................................................................................... 57 6 Message Publishing
................................................................................................................................... 65 7 Publish Push Notifications
................................................................................................................................... 67 8 Cancel Scheduled Message
................................................................................................................................... 68 9 Message Subscription
................................................................................................................................... 72 10 Cancel Subscription
File Service
73
................................................................................................................................... 73 1 Overview
................................................................................................................................... 73 2 Setup
................................................................................................................................... 74 3 Sync and Async Calls
................................................................................................................................... 75 4 Error Handling
................................................................................................................................... 76 5 File Upload
................................................................................................................................... 77 6 File Download
................................................................................................................................... 78 7 File Deletion
................................................................................................................................... 79 8 Directory Deletion
................................................................................................................................... 80 9 Git Integration
................................................................................................................................... 80 10 Web Hosting
................................................................................................................................... 81 11 Custom Domain Name
................................................................................................................................... 82 12 Custom Web Template Hosting
................................................................................................................................... 85 13 Files Security
Geo Service
86
................................................................................................................................... 86 1 Overview
................................................................................................................................... 88 2 Setup
................................................................................................................................... 89 3 Error Handling
................................................................................................................................... 90 4 Adding a Geo Category
................................................................................................................................... 93 5 Deleting a Geo Category
................................................................................................................................... 95 6 Retrieving Geo Categories
................................................................................................................................... 96 7 Adding a Geo Point
................................................................................................................................... 97 8 Updating a Geo Point
................................................................................................................................... 98 9 Importing Geo Data
................................................................................................................................... 99 10 Search in Category
................................................................................................................................... 102 11 Search in Radius
................................................................................................................................... 106 12 Search in Rectangular Area
................................................................................................................................... 109 13 Partial Match Search
Index 110
User Service
2014 Backendless Corp.
5
1 User Service
1.1 Overview
The Backendless User Service empowers applications with the functionality related to the user accounts
such as user registrations, logins, password recovery and logouts. The core concept which the User
Service relies on is the User entity. The structure of the entity is configurable, that is a developer can
decide which properties "describe" a user in the context of a given version of the application. Typically,
properties describing a user are the ones collected during the user registration process. The User
Service provides the API enabling the following functionality for the applications built on top of
Backendless:
User Registration - Applications use the Backendless' registration API to let the users register
and create accounts for subsequent logins. Application developers can restrict access to the
server-side resources for specific user accounts or based on roles.
User Login - the API lets the registered users login to establish their identity within the
application.
Password Recovery - Backendless supports a complete workflow allowing users to recover lost or
forgotten passwords.
User Logout - the API lets the logged in users terminate their session and disassociate their
identity from the application.
Updating User Registration - the API supports the operation of updating user information.
1.2 Setup
To get access to the Backendless services, JavaScript applications must reference the backendless.js
library available in the Backendless SDK for JavaScript. Alternatively, the latest version of the library can
be loaded from the following URLs:
non-compressed library:
http://api.backendless.com/sdk/js/latest/backendless.js
compressed library:
http://api.backendless.com/sdk/js/latest/backendless.min.js
Before the JavaScript client uses any of the APIs, the code must initialize the Backendless Application
using the following call:
Backendless.initApp( application-Id, secret-key, version )
Values for the application-id and secret-key headers must be obtained through the Backendless
Console:
1. Login to your account and select the application.
2. Click the Manage icon from the vertical icon-menu on the left.
3. The "App Settings" section is selected by default. The interface contains the text fields for
"Application ID" and secret keys for each supported client-side environment.
4. Use the "Copy" button to copy the value into the system clipboard.
Backendless API for JavaScript
2014 Backendless Corp.
6
Make sure to use the "JavaScript Secret Key" for the secret-key argument.
The version argument must contain the name of the targeted version. When a new application is
created, the default version name is "v1". To manage versions, login to the console, select the
"Manage" icon and click "Versioning".
1.3 Core Classes
The Backendless User Service uses the following core classes:
Backendless.UserService - provides access to the user service API. All user-related operations,
such as user registration, user update, login, logout and password recovery are available through this
class.
Backendless.User - represents a user registered with the application. The class is used in:
User Registration - an instance of the class contains a list of user properties
User Registration/Properties Update - an instance of the class contains a list of properties to be
updated
The Login method returns an instance of the class upon successful login.
The Backendless.User definition contains only one field - password. All other fields can be defined
on the fly - see User Registration for details.
Backendless.Async - a construct used in the asynchronous API calls. Must reference two functions:
one accepting a result from the server and the other for handling errors reported by the server.
Backendless.Async Definition
User Service
2014 Backendless Corp.
7
The Backendless.Async function is defined as:
function Async( successCallback );
function Async( successCallback, context );
function Async( successCallback, faultCallback, context );
Backendless.Async = Async;
where:
successCallback - a reference to a function which will be called when the server returns a
result. The signature of this callback function must accept one argument
which will be the actual result object returned by the server.
faultCallback - an (optional) reference to a function which will be called if the server
returns an error. The function must accept one argument which is a fault
object containing the information about the error.
context - an (optional) reference to the object which is used as "this" when
calling successCallback or faultCallback
1.4 Error Handling
When the server reports an error, it is delivered to the client through a fault object, which is an untyped
JavaScript object. The fault object has the same structure for both synchronous and asynchronous
invocations:
{
"message": value,
"statusCode": value
}
where:
message - contains a string value with the description of the error
statusCode - error code as a string value. Currently all the error codes are numbers,
however the method returning the error code returns the String type. This is
done for future expansion of the error code system which may include
characters.
The asynchronous calls receive the fault through the fault callback referenced in the Async function.
For the synchronous calls the fault object is thrown as an error which must be handled in a catch( err
) block:
try
{
backendlessAPIcall();
}
catch( err )
{
console.log( "Error message - " + err.message );
console.log( "Error code - " + err.statusCode );
}
1.5 User Properties
When a user registers with an application, he provides information which establishes the person's
identity. For one application these properties may include name, phone number and email address, for
Backendless API for JavaScript
2014 Backendless Corp.
8
another it could be user id, age and gender. Backendless User Service allows each application to have a
custom set of properties associated with the user entity. There are two ways to define what properties
the User entity should have in a Backendless application:
Defining properties with Console
User property management is available on the User Properties screen of the console. To get to the
screen:
1. Login to the console
2. Select the desired application and version
3. Click the Users icon on the left side of the interface. The "User Properties" panel is selected by
default.
The interface consists of two lists: Available Properties and Selected Properties. The Selected
Properties list contains the properties assigned to the User entity - these are the effective properties for
the selected version of the application. The Available Properties list is simply a storage for the non-
effective properties which can be moved to the Selected list if needed. A property can be moved between
the lists by clicking its name.
Identity Property
Among the Selected Properties, one must be marked as identity. This is the property Backendless
uses for the Login and Restore Password operations.. As users register, Backendless ensures the
provided value for the property selected as identity is unique in the context of a specific version for
an application.
Password Property
"password" is a special property. Backendless automatically adds the property when an application
is created. The following rules apply to the password property:
Password cannot be moved out of the Available Properties list.
Password cannot be marked as Identity.
Password is always a required property
User Service
2014 Backendless Corp.
9
To add a property, click the "Add Custom Property" button. New properties automatically added to the
Selected Properties list. To move a property to the other list, simply click its name.
Defining properties with API
User properties can be defined with the user registration API call. For any property specified in the
object with the user registration information Backendless creates a user property. This behavior can be
turned off/on using the Dynamic User Definition configuration setting in the console (select the Users >>
User Properties). The setting is turned on by default:
1.6 Retrieve User Entity Properties
Application developers can get a list of the properties associated with the user entity using the following
API:
Asynchronous Call Method Signature:
The method call does not block - it returns immediately. The Backendless.Async argument receives
either the response or the fault returned by the Backendless servers.
Backendless.UserService.describeUserClass( Backendless.Async
callback );
where:
callback - an an instance of Backendless.Async which receives either a return value or an error
from the server. The return value from the server is an array of the objects describing
properties of the User entity for the specified version of the application. The structure of
the object in the response array is:
{
// name of the property
"name": value,
// indicates whether the property is required for user
registration
"required": true or false,
// property data type
"type": value,
// default value of the property if one is not provided
during registration
"defaultValue": value or null,
// indicates whether the property is marked as user
identity
"identity": true or false
}
Synchronous Call Method Signature:
Backendless API for JavaScript
2014 Backendless Corp.
10
Backendless.UserService.describeUserClass();
The method's return value is an array of the objects describing properties of the User entity for the
specified version of the application. See above for the object's structure.
Asynchronous Call Example:
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
function gotPropertyDesc( props )
{
for( i in props )
{
console.log( "property name - " + props[ i ].name );
console.log( "\tis property required - " + props[ i ].
required );
console.log( "\tproperty data type - " + props[ i ].type );
console.log( "\tdefault value - " + props[ i ].defaultValue );
console.log( "\tis property identity - " + props[ i ].
identity );
}
}
function gotError( err ) // see more on error handling
{
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
Backendless.UserService.describeUserClass( new Backendless.Async
( gotPropertyDesc, gotError ) );
Synchronous Call Example:
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
var props = Backendless.UserService.describeUserClass();
for( i in props )
{
console.log( "property name - " + props[ i ].name );
console.log( "\tis property required - " + props[ i ].required );
console.log( "\tproperty data type - " + props[ i ].type );
console.log( "\tdefault value - " + props[ i ].defaultValue );
console.log( "\tis property identity - " + props[ i ].identity );
}
1.7 User Registration
The user registration API can be used to create user accounts in the application. The registration
request must provide a user object as a collection of key/value properties. The collection must contain
all the required properties which must include a property marked as identity as well as the "password"
User Service
2014 Backendless Corp.
11
property. Unless the properties are modified in the console, the default property marked as identity is
"email". Additionally, the "email" property is required if the application is configured to confirm email
addresses for the registered users.
Asynchronous Call Method Signature:
The method call does not block - it returns immediately. The Backendless.Async argument receives
either the response or the fault returned by the Backendless servers.
Backendless.UserService.register( user, asyncCallback );
where:
user - an instance of the Backendless.User class which contains property values
for the account registration.
asyncCallback - an instance of Backendless.Async. Receives either a return value or an error
from the server. The return value from the server is an instance of the
Backendless.User class with the ID assigned by the server-side.
Synchronous Call Method Signature:
Backendless.UserService.register( user );
where:
user - an instance of the Backendless.User class which contains property values
for the account registration.
Error Codes:
The following errors may occur during User Registration API calls. See the Error Handling section for
details on how to retrieve the error code when the server returns an error.
Error
Code
Description
2002 Version is disabled or provided wrong application info (application id or
secret key)
3009 User registration is disabled for the version of the application
3010 User registration has an unknown property and dynamic properties are
disabled for this version of the application
3011 Missing "password" property
3012 Required property is missing
3013 Missing value for the identity property
3014 External registration failed with an error.
3021 General user registration error. Details included with the error message.
3033 User with the same identity already exists
3038 Missing application-id, version name or collection of properties for the
registering user
3039 Property "id" cannot be used in the registration call
3040 Email address is in the wrong format
3041 A value for a required property is missing
3043 Duplicate properties in the registration request
8000 Property value exceeds the length limit
Backendless API for JavaScript
2014 Backendless Corp.
12
Asynchronous Call Example:
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
function userRegistered( user )
{
console.log( "user has been registered" );
}
function gotError( err ) // see more on error handling
{
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
var user = new Backendless.User();
user.email = "james.bond@mi6.co.uk";
user.password = "iAmWatchingU";
Backendless.UserService.register( user, new Backendless.Async
( userRegistered, gotError ) );
Synchronous Call Example:
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
var user = new Backendless.User();
user.email = "james.bond@mi6.co.uk";
user.password = "iAmWatchingU";
try
{
Backendless.UserService.register( user );
}
catch( err )
{
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
Turning Registration Off
User registration can be disabled for a particular version of the application using the Backendless
Console:
1. Login to the console and select the application.
2. Click the "Users" icon in the vertical icon menu on the left.
3. Click "Registration".
The "Registration" toggle turns the registration API on or off. When the registration is turned off and a
user attempts to register, the system returns error 3009.
User Service
2014 Backendless Corp.
13
Email Confirmations
Backendless can send out an email requesting new registered users to confirm their email address. This
feature can be configured in the Backendless Console:
1. Log into the console and select the application.
2. Click the "Users" icon in the vertical icon menu on the left.
3. Click "Registration".
When email confirmations are required (the feature is enabled by default), the "email" user property is
required and must contain a value formatted as an email address. To configure the text of the email
message, select "Communication & Email Templates" from the Users menu in the console and select
the "User registers" event.
External Registration
User registrations can be duplicated in an external system through the External Registration Callback.
Developer can specify a URL where Backendless sends a POST request to with the user registration
data as a JSON object. The external registration callback is synchronous and takes place in the same
transaction as the Backendless registration call. As a result, the external system must return result as
fast as possible. The format of the request and response for the external registration is the same as the
request/response body of the Backendless registration API.
To configure the callback:
1. Login to the console and select the application.
2. Click the "Users" icon in the vertical icon menu on the left.
3. Click "Registration".
4. Turn on the "Execute registration callback" toggle.
5. Enter the URL of the script into the "Callback URL" text field.
1.8 Login
Registered users can login to establish their identity with the application using the API below. The login
operation requires two properties: one marked as user identity and the second is password.
Backendless automatically assigns the "AuthenticatedUser" role to all successfully logged in users.
The role can be used to differentiate access to various resources (persistent objects, messaging
channels, media streams) between authenticated users and guests.
Asynchronous Call Method Signature:
Backendless API for JavaScript
2014 Backendless Corp.
14
The method call does not block - it returns immediately. The AsyncCallback argument receives either
the response or the fault returned by the Backendless servers.
Backendless.UserService.login( login, password, asyncCallback );
where:
login - a value for the property marked as identity.
password - user's password
asyncCallback - an instance of Backendless.Async. Receives either a return value or an error
from the server. The return value from the server is an instance of the
Backendless.User class representing the logged in user.
Synchronous Call Method Signature:
Backendless.UserService.login( login, password );
where:
login - a value for the property marked as identity.
password - user's password
Error Codes:
The following errors may occur during the Login API call. See the Error Handling section for details on
how to retrieve the error code when the server returns an error.
Error
Code
Description
2002 Version is disabled or provided wrong application info (application id or
secret key)
3000 Login has been disabled for the user account.
3001 Missing login settings, possibly invalid application id or version.
3002 User cannot login because Multiple Logins disabled and there is a logged
in user for the account.
3003 Invalid login or password.
3006 Either login or password is an empty string value.
3034 User logins are disabled for the version of the application.
3036 Account locked out due to too many failed logins.
3038 One of the required parameters (application id, version, login or password)
is null
3044 Multiple login limit for the same user account has been reached.
8000 Property value exceeds the length limit
Asynchronous Call Example:
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
function userLoggedIn( user )
{
console.log( "user has logged in" );
}
User Service
2014 Backendless Corp.
15
function gotError( err ) // see more on error handling
{
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
Backendless.UserService.login( login, password, new Backendless.
Async( userLoggedIn, gotError ) );
Synchronous Call Example:
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
var user;
try
{
user = Backendless.UserService.login( username, password );
}
catch( err ) // see more on error handling
{
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
External Authentication
Similar to external registration, Backendless supports external authentication. When configured,
Backendless delegates the authentication process to an external system by sending the provided user
credentials to a URL. The URL of the external authentication system can be configured in Backendless
Console:
1. Log into the console and select the application.
2. Click the "Users" icon in the vertical icon menu on the left.
3. Click "Login".
4. The "External authentication" section contains the configuration settings.
When the external authentication is enabled and user attempts to login, Backendless sends the
following request to the specified URL:
GET http://external-authentication-url
Authorization: Basic base64-encoded-login:password
Where base64-encoded-login:password is constructed as follows:
1. login and password are combined into a string "login:password"
2. The resulting string literal is then encoded using Base64
Backendless API for JavaScript
2014 Backendless Corp.
16
Multiple Logins
The Multiple Logins feature enables login using the same account from different computers or devices.
Multiple logins can be configured in the Backendless Console:
1. Log into the console and select the application.
2. Click the "Users" icon in the vertical icon menu on the left.
3. Click "Login".
4. The "Multiple Logins" section contains the configuration settings.
When the feature is turned on (multiple logins allowed), the configuration setting may include the
maximum number of simultaneous logins for the selected version of the application. When the feature is
disabled (multiple logins are not allowed), the configuration must indicate whether which login should be
invalidated (first or second for the account):
Session Timeout
Backendless supports session expiration which can be configured in console. Along with the session
timeout interval, the configuration can also include a forwarding URL which is used to redirect requests
to for the expired sessions.
Account Lockout
An application powered by Backendless can be configured to lock out accounts with failed logins. The
console has two configuration options: number of failed logins before the account is locked and a time
interval to wait before the account is available for logins again.
User Service
2014 Backendless Corp.
17
1.9 Update User Properties
Backendless supports the operation of user properties update for the logged in users. This operation is
useful if an application needs to provide to the users the functionality for updating user profiles and
registration properties. User must be logged in in order to update his registration properties.
Asynchronous Call Method Signature:
The method call does not block - it returns immediately. The AsyncCallback argument receives either
the response or the fault returned by the Backendless servers.
Backendless.UserService.update( user, asyncCabback );
where:
user - an instance of the Backendless.User class which contains property values to
be updated for the account.
asyncCallback - an instance of Backendless.Async. Receives either a return value or an error
from the server. The return value from the server is an instance of the
Backendless.User class with the ID assigned by the server-side.
Synchronous Call Method Signature:
Backendless.UserService.update( user );
where:
user - an instance of the Backendless.User class which contains property values to
be updated for the account.
Error Codes:
The following errors may occur during the Update User Properties API call. See the Error Handling
section for details on how to retrieve the error code when the server returns an error.
Error
Code
Description
2002 Version is disabled or provided wrong application info (application id or
secret key)
3018 The property marked as "identity" is being updated and another user
already has the specified value which must be unique.
3024 General "update registration" error. Error message should contain
additional details.
3028 User is not logged in.
Backendless API for JavaScript
2014 Backendless Corp.
18
3029 Cannot modify properties of another user. Returned when one user is
logged and the call attempts to modify properties of another user.
3030 Unable to locate user account - invalid user id.
3031 A new "dynamic" property is being added, but dynamic property definition
is disabled.
3045 Required properties in the provided object do not contain values.
Asynchronous Call Example:
var loggedInUser;
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
function userLoggedIn( user )
{
loggedInUser = user;
updateUser();
}
function gotError( err ) // see more on error handling
{
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
function userUpdated( user )
{
console.log( "user has been updated" );
this.loggedInUser = user;
}
function updateUser()
{
user.address = "123 Main St";
Backendless.UserService.login( user, new Backendless.Async
( userUpdated, gotError ) );
}
Backendless.UserService.login( login, password, new Backendless.
Async( userLoggedIn, gotError ) );
Synchronous Call Example:
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
var user;
try
{
user = Backendless.UserService.login( username, password );
User Service
2014 Backendless Corp.
19
}
catch( err )
{
// login failed
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
try
{
user.phoneNumber = "5551212";
user = Backendless.UserService.update( user );
}
catch( err )
{
// update failed
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
1.10 Get Current User
A JavaScript application can retrieve an instance of Backendless.User representing the currently logged
in user using the following API call:
Backendless.UserService.getCurrentUser();
If a user is not logged in, the method returns null.
1.11 Logout
The Logout operation terminates user session and disassociates the AuthenticatedUser role from the
subsequent requests made by the client application.
Asynchronous Call Method Signature:
The method call does not block - it returns immediately. The AsyncCallback argument receives either
the response or the fault returned by the Backendless servers.
Backendless.UserService.logout( asyncCallback )
where:
asyncCallback - an instance of Backendless.Async. Receives either a notification or an error
from the server.
Synchronous Call Method Signature:
Backendless.UserService.logout()
Error Codes:
The following errors may occur during the Logout API call. See the Error Handling section for details on
how to retrieve the error code when the server returns an error.
Error
Code
Description
2002 Version is disabled or provided wrong application info (application id or
Backendless API for JavaScript
2014 Backendless Corp.
20
secret key)
3007 Invalid application-id or version.
3023 General error while executing logout. Error details should be available in
the message property.
Asynchronous Call Example:
var loggedInUser;
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
function userLoggedIn( user )
{
loggedInUser = user;
logoutUser();
}
function gotError( err ) // see more on error handling
{
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
function userLoggedout()
{
console.log( "user has been logged out" );
}
function logoutUser()
{
Backendless.UserService.logout( new Backendless.Async
( userLoggedout, gotError ) );
}
Backendless.UserService.login( login, password, new Backendless.
Async( userLoggedIn, gotError ) );
Synchronous Call Example:
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
BackendlessUser user;
try
{
user = Backendless.UserService.login( username, password );
}
catch( err ) // see more on error handling
{
// login failed, to get the error code, call err.statusCode
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
User Service
2014 Backendless Corp.
21
}
try
{
// now log out:
Backendless.UserService.logout();
}
catch( err ) // see more on error handling
{
// logout failed, to get the error code, call err.statusCode
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
1.12 Password Recovery
Password recovery sends an email to the user's email address with a link where the user can change
the password.
Asynchronous Call Method Signature:
The method call does not block - it returns immediately. The AsyncCallback argument receives either
the response or the fault returned by the Backendless servers.
Backendless.UserService.restorePassword( identityValue,
asyncCallback )
where:
identityValue - a value for the property marked as identity.
asyncCallback - an instance of Backendless.Async. Receives either a notification or an error
from the server.
Synchronous Call Method Signature:
Backendless.UserService.restorePassword( identityValue )
where:
identityValue - a value for the property marked as identity.
Error Codes:
The following errors may occur during the Password Recovery API call. See the Error Handling section
for details on how to retrieve the error code when the server returns an error.
Error
Code
Description
2002 Version is disabled or provided wrong application info (application id or
secret key)
3020 Unable to find user with the specified login (invalid user identity).
3025 General password recovery error. Additional details should be available in
the "message" property of the response.
3038 One of the requirement arguments (application id, version or user identity)
is missing.
Asynchronous Call Example:
Backendless API for JavaScript
2014 Backendless Corp.
22
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
function passwordRecoverySent( user )
{
console.log( "an email with a link to restore password has been
sent to the user" );
}
function gotError( err ) // see more on error handling
{
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
var async = new Backendless.Async( passwordRecoverySent,
gotError );
Backendless.UserService.restorePassword( login, async );
Synchronous Call Example:
Backendless.initApp( appId, secretKet, version ); // where to get
the argument values for this call
try
{
Backendless.UserService.restorePassword( login, async )
}
catch( err ) // see more on error handling
{
console.log( "error message - " + err.message );
console.log( "error code - " + err.statusCode );
}
1.13 Security
All Backendless API operations can be restricted either for specific user accounts or for roles. A user
account may be associated with one or more roles. Backendless supports several built-in system roles
as well as developer-defined roles. The system roles include:
NotAuthenticatedUser - any user who has not authenticated to a Backendless application.
AuthenticatedUser - any user who has successfully logged in.
SocialUser - any user who has logged in through a social network.
FacebookUser - any user who has logged in with a Facebook account.
TwitterUser - any user who has logged in with a Twitter account.
Developer-defined roles can be added using the Backendless Console. Roles are defined at the
application version level, that is a particular version of an application may have its own set of developer-
defined roles.
Backendless manages permissions as tuples consisting of:
Operation - Users interact with Backendless either via console or the API. Any request to
Backendless is an operation which may have a permission associated with it.
User Service
2014 Backendless Corp.
23
Resource - Some operations target specific resources. These can be data tables, messaging
channels or media tubes.
Principal - Either a specific user identity or a role associated with the user initiating the operation.
There are two levels of permissions for the API operations - global and resource-specific. The resource-
specific permissions guard access to the specific resources (data tables, messaging channels, etc).
They have higher priority and are checked first. When Backendless receives an API call from a client, it
determines the user associated with the request and obtains a list of roles associated with the user
account (for the users who have not authenticated, the NotAuthenticatedUser role is used). The
resource-specific permissions can be set to either inherit the permission from the global matrix or
explicitly grant or deny access to the resource for the given user or role. The diagram below illustrates
the process when the resource-specific permission is set to inherit:
When the resource-specific permission is explicitly set to either grant or deny access, the global
permissions are bypassed:
Backendless API for JavaScript
2014 Backendless Corp.
24
Global Permissions
The global service permissions apply to all resources managed by a particular service. For example,
global Data Service permissions for a particular role apply to all data tables. These permissions can be
viewed and modified by clicking a role on the Users > Security and Restrictions screen in Backendless
Console:
User Service
2014 Backendless Corp.
25
The table below shows a global permissions matrix for a role:
Backendless API for JavaScript
2014 Backendless Corp.
26
Each global permission has two states:
Grant - represented by a green check mark - grants the rights to execute an operation
Deny - represented by a red X - denies the rights to execute an operation.
To change a permission click the icon of the current state. The change will be effective immediately.
To register a new role use the "Add Role" button on the "Security and Restrictions" screen. Once a role
is added, you can configure it's global permission matrix as well as resource-specific permissions.
Resource-Specific Permissions
To view, assign or modify resource-specific permissions, use a corresponding screen in the
Backendless Console. For example, to restrict access to a data table, switch to the Data view, select a
table and click the "Schema and Permissions" button. The user interface has two views - one is for
managing permissions for user accounts and the other for roles. To modify permissions for a user
account:
1. Click the "User Permissions" list item.
2. Enter the user name in the search field.
3. Select the user and click the "Add" button.
4. The table displays the permissions for various operations for the selected user and the resource.
5. Click an icon representing the permission state to modify the permission.
User Service
2014 Backendless Corp.
27
Similarly permissions can be assigned or modified for specific roles - use the "Role Permissions" list
item.
To modify the permissions for Messaging channels, click the "Messaging" icon, select a channel and
switch to the "Permissions" view.
1.14 Role to User Mapping
User accounts can be mapped to roles using the API documented below. Once a role is assigned to a
user account, any permissions assigned to the role (both grant and deny) automatically apply to all API
operations executed by the application on behalf of the user.
Assigning a Role to User:
Asynchronous Call Method Signature:
The method call does not block - it returns immediately. The AsyncCallback argument receives either
the response or the fault returned by the Backendless servers.
Backendless.UserService.assignRole( user, role, asyncCallback );
where:
user - user identification. A value for the property marked as identity.
role - name of the role to assign to the user account.
asyncCallback - an instance of Backendless.Async. Receives either a return value or an
error from the server.
Synchronous Call Method Signature:
Backendless.UserService.assignRole( user, role );
where:
user - user identification. A value for the property marked as identity.
role - name of the role to assign to the user account.
Unassigning a Role from User:
Asynchronous Call Method Signature:
The method call does not block - it returns immediately. The asyncCallback argument receives either
the response or the fault returned by the Backendless servers.
Backendless.UserService.unassignRole( user, role, asyncCallback );
where:
user - user identification. A value for the property marked as identity.
role - name of the role to assign to the user account.
asyncCallback - an instance of Backendless.Async. Receives either a return value or an
error from the server.
Synchronous Call Method Signature:
Backendless API for JavaScript
2014 Backendless Corp.
28
Backendless.UserService.unassignRole( user, role );
where:
user - user identification. A value for the property marked as identity.
role - name of the role to assign to the user account.
Error Codes:
The following errors may occur during the Login API call. See the Error Handling section for details on
how to retrieve the error code when the server returns an error.
Error
Code
Description
2002 Version is disabled or provided wrong application info (application id or
secret key)
2005 Could not find role.
3038 One of the required parameters (user identity or roleName) is null.
3057 Could not find user by id or identity.
3058 Could not assign role to user.
3059 Could not unassign role to user.
2 Data Service
2.1 Overview
The Backendless Data Service is a highly scalable, object storage system. It is available via intuitive API
which supports all basic data persistence operations - Create, Retrieve, Update and Delete (CRUD). The
Data Service operates with persistent data at the object level, that means applications use the APIs to
save, update, delete or search for objects, rather than traditional database records. Developers using the
Data Service API do not need to know or understand the databases, schema creation rules, stored
procedures or SQL syntax.
The Data Service follows the following rules when working with user objects:
1. Objects persisted by the Data Service must specify the "type" or be an instance of a class (for
client applications written in strongly-typed languages).
2. Backendless automatically creates tables for each persisted type it has not seen before and
saves objects in the corresponding tables. Each table has columns corresponding to the
properties of the persisted objects.
3. Backendless creates three additional system-level columns for each new table:
objectId - contains a unique object ID assigned by Backendless to each object.
created - contains a timestamp when the object was first saved by Data Service
updated - contains a timestamp when the object was most recently updated. The value is
null for newly created objects.
4. When an object of a known type/class introduces any new properties throughout the lifetime of
the application, the persistence structure will be modified accordingly. When such an object is
persisted, Backendless analyzes the object's properties and automatically alters the structure of
the corresponding table if any new properties are added.
5. When an object is saved or updated, it may reference another related object (a one-to-one
relationship) or objects (one-to-many). Backendless creates the underlying tables for the main
and the referenced types and persists the hierarchy accordingly.
Data Service
2014 Backendless Corp.
29
2.2 Setup
To get access to the Backendless services, JavaScript applications must reference the backendless.js
library available in the Backendless SDK for JavaScript. Alternatively, the latest version of the library can
be loaded from the following URLs:
non-compressed library:
http://api.backendless.com/sdk/js/latest/backendless.js
compressed library:
http://api.backendless.com/sdk/js/latest/backendless.min.js
Before the JavaScript client uses any of the APIs, the code must initialize the Backendless Application
using the following call:
Backendless.initApp( application-Id, secret-key, version )
Values for the application-id and secret-key headers must be obtained through the Backendless
Console:
1. Login to your account and select the application.
2. Click the Manage icon from the vertical icon-menu on the left.
3. The "App Settings" section is selected by default. The interface contains the text fields for
"Application ID" and secret keys for each supported client-side environment.
4. Use the "Copy" button to copy the value into the system clipboard.
Make sure to use the "JavaScript Secret Key" for the secret-key argument.
Backendless API for JavaScript
2014 Backendless Corp.
30
The version argument must contain the name of the targeted version. When a new application is
created, the default version name is "v1". To manage versions, login to the console, select the
"Manage" icon and click "Versioning".
2.3 Sync and Async Calls
Most of Backendless API for JavaScript methods are available in the synchronous and asynchronous
formats. The difference in the method signatures is the asynchronous methods accept the Async
argument:
function Async( successCallback, faultCallback, context )
where:
successCallback - a function to be called when the asynchronous operation returns
result. The function argument is the return value for the asynchronous
operation.
faultCallback - a function to be called if the asynchronous operation returns an error.
The function argument is a fault object describing the error.
context - An optional argument, if provided is an object establishing the context
for the successCallback and faultCallback methods
2.4 Error Handling
When the server reports an error, it is delivered to the client through a fault object, which is an untyped
JavaScript object. The fault object has the same structure for both synchronous and asynchronous
invocations:
{
"message": value,
"statusCode": value
}
where:
message - contains a string value with the description of the error
statusCode - error code as a string value. Currently all the error codes are numbers,
however the method returning the error code returns the String type. This is
done for future expansion of the error code system which may include
characters.
The asynchronous calls receive the fault through the fault callback referenced in the Async function.
For the synchronous calls the fault object is thrown as an error which must be handled in a catch( err
) block:
try
{
backendlessAPIcall();
}
catch( err )
{
console.log( "Error message - " + err.message );
console.log( "Error code - " + err.statusCode );
}
Data Service
2014 Backendless Corp.
31
2.5 Data Object
Backendless supports persistence of arbitrary (typed or untyped) JavaScript objects. There are a few
requirements imposed on the structure of the persisted objects:
Class must declare at least one property.
Backendless automatically assigns a unique ID to every persisted object. If the application needs
to have access to the assigned ID, it can obtain it using a dynamically assigned property. Do NOT
declare the objectId property - it will change the persistence behavior when objects are created in
a remote data store:
var objectId = persistedDataObject["objectId"];
In addition to objectId, Backendless maintains two additional properties for every persisted
object - created and updated. The former contains the timestamp when the object was initially
created in the Backendless data store. The latter is updated every time the object is updated. To
get access to these values use the dynamically assigned properties:
var createdTime = persistedDataObject["created"];
var updatedTime = persistedDataObject["updated"];
2.6 Saving Data Objects
The API to save an object can be used for two separate scenarios: if an object has been previously
saved, it is updated in the data store, otherwise it is saved (created). The save operation checks if the
object has objectId assigned by the server. in that case, the object is updated, otherwise it is created
in the Backendless data store. In case when there is no table for the persisted object, Backendless
creates one and maps table's columns to the object's properties.
The objectId property is automatically assigned to all persisted objects when they are initially saved.
See the Data Object section for details on objectId.
Backendless.Persistence.of( constructor-function ).save( entity,
async )
Arguments:
constructor-function - a reference to a JavaScript constructor function defining a
JavaScript class. The entity argument must be an instance of
this class.
entity - a JavaScript object to persist, must be an instance of JS-
Class.
async - Optional argument. If provided, the method is executed
asynchronously. The successCallback function referenced in
the async object receives a callback when the method
successfully saves the object. If an error occurs, the
faultCallback function is invoked. See Sync and Async Calls
for additional details.
Return Value:
If the method is invoked synchronously, it returns the saved object. The asynchronous call
receives the return value through a callback executed on the Async object.
Example:
Consider the following class:
function Contact(args) {
args = args || {};
Backendless API for JavaScript
2014 Backendless Corp.
32
this.name = args.name || "";
this.age = args.age || "";
this.phone = args.phone || "";
this.title = args.title || "";
}
The following code saves a new instance of the Contact class:
var APPLICATION_ID = "YOUR-APP-ID",
SECRET_KEY = "YOUR-SECRET-KEY",
VERSION = "v1"; //default application version;
Backendless.initApp( APPLICATION_ID, SECRET_KEY, VERSION );
var contactObject = new Contact( {
name: "James Bond",
age: 45,
phone: "1-800-JAMESBOND",
title: "chief spying officer"
});
var savedContact = Backendless.Persistence.of( Contact ).save
( contactObject );
2.7 Updating Data Objects
Updating a data object which has been previously stored in the Backendless data store can be done
using the same API as for saving the initial object version. Once an object has objectId assigned, the
call updates the persisted copy of the object:
Backendless.Persistence.of( constructor-function ).save( entity,
async )
Arguments:
constructor-function - a reference to a JavaScript constructor function defining a
JavaScript class. The entity argument must be an instance of
this class.
entity - a JavaScript object to update, must be an instance of JS-
Class.
async - Optional argument. If provided, the method is executed
asynchronously. The successCallback function referenced in
the async object receives a callback when the method
successfully saves the object. If an error occurs, the
faultCallback function is invoked. See Sync and Async Calls
for additional details.
Return Value:
If the method is invoked synchronously, it returns the saved object. The asynchronous call
receives the return value through a callback executed on the Async object.
Example:
Consider the following class:
function Contact(args) {
args = args || {};
Data Service
2014 Backendless Corp.
33
this.name = args.name || "";
this.age = args.age || "";
this.phone = args.phone || "";
this.title = args.title || "";
}
The following code saves a new instance of the Contact class:
var APPLICATION_ID = "YOUR-APP-ID",
SECRET_KEY = "YOUR-SECRET-KEY",
VERSION = "v1"; //default application version;
Backendless.initApp( APPLICATION_ID, SECRET_KEY, VERSION );
var contactObject = new Contact( {
name: "James Bond",
age: 45,
phone: "1-800-JAMESBOND",
title: "chief spying officer"
});
var savedContact = Backendless.Persistence.of( Contact ).save
( contactObject );
savedContact["phone"] = "1-800-BOND-JAMES-BOND";
savedContact["title"] = "ladies man";
contactStorage.save( savedContact );
2.8 Deleting Data Objects
The API completely removes an object from the persistent store. If the object is successfully delete, the
API returns the timestamp of the exact deletion time in milliseconds.
Backendless.Persistence.of( constructor-function ).remove
( dataObject, async );
Arguments:
constructor-function - a reference to a JavaScript constructor function defining a
JavaScript class. The dataObject argument must be an
instance of the class.
dataObject - a JavaScript object to remove, must be an instance of JS-
Class, alternatively the argument can be objectId of the object
to remove.
async - Optional argument. If provided, the method is executed
asynchronously. The successCallback function referenced in
the async object receives a callback when the method
successfully removed the object. If an error occurs, the
faultCallback function is invoked. See Sync and Async Calls
for additional details.
Return Value:
The synchronous method returns the time stamp when the server-side removed the object from
the data store. The asynchronous call receives the return value through a callback executed on
the Async object
Example:
Consider the following class:
Backendless API for JavaScript
2014 Backendless Corp.
34
function Contact(args) {
args = args || {};
this.name = args.name || "";
this.age = args.age || "";
this.phone = args.phone || "";
this.title = args.title || "";
}
The following code saves and then deleted an instance of the Contact class:
var APPLICATION_ID = "YOUR-APP-ID",
SECRET_KEY = "YOUR-SECRET-KEY",
VERSION = "v1"; //default application version;
Backendless.initApp( APPLICATION_ID, SECRET_KEY, VERSION );
var contactObject = new Contact( {
name: "James Bond",
age: 45,
phone: "1-800-JAMESBOND",
title: "chief spying officer"
});
var savedContact = Backendless.Persistence.of( Contact ).save
( contactObject );
contactStorage.remove( savedContact );
2.9 Basic Search
Backendless supports multiple basic search operations. These include finding an object by ID, finding
first or last object in the collection or retrieving the entire persisted collection. Each method is available
in both synchronous and asynchronous versions:
Retrieve all data objects of the type defined by constructor-function:
var dataCollection = Backendless.Persistence.of( constructor-function ).find
( async );
Find first data object of the type defined by constructor-function. The first data object is the first
one saved in the data store:
var dataObject = Backendless.Persistence.of( constructor-function ).findFirst
( async );
Find last data object of the type defined by constructor-function. The last data object is the last
one saved in the data store:
var dataObject = Backendless.Persistence.of( constructor-function ).findLast
( async );
Find a data object by its ID:
var dataObject = Backendless.Persistence.of( constructor-function ).findById
( async );
Arguments:
constructor-function - a reference to a JavaScript constructor function defining a
Data Service
2014 Backendless Corp.
35
JavaScript class. Object(s) returned by functions will be of the
specified type.
async - Optional argument. If provided, the method is executed
asynchronously. The successCallback function referenced in
the async object receives a callback when the method
successfully removed the object. If an error occurs, the
faultCallback function is invoked. See Sync and Async Calls
for additional details.
Return Value:
dataObject - An object of type defined by constructor-function.
dataCollection - A collection of objects. Each object is of type defined by
constructor-function. The collection has the following
structure:
{
"nextPage":value,
"data": [ array of data objects defined
by constructor-function ],
"offset":value,
"totalObjects":value
}
where:
nextPage - is a REST URL returning the next
page of data.
data - is an array of data objects.
offset - is a numeric value defining the index
in the data store from where the
current page of data is returned.
totalObjects - is a total number of all data objects
found through the search request. If
the length of the "data"array is a
smaller number than "totalObjects, it
means an additional request must be
made to load the next page of data.
Alternatively, use an advanced
search function with a custom page
size.
Example:
Consider the following class:
function Contact(args) {
args = args || {};
this.name = args.name || "";
this.age = args.age || "";
this.phone = args.phone || "";
this.title = args.title || "";
}
The following code demonstrates various search queries:
Find all objects:
var contactsCollection = Backendless.Persistence.of( Contact ).find();
Find first object:
var firstContact = Backendless.Persistence.of( Contact ).findFirst();
Backendless API for JavaScript
2014 Backendless Corp.
36
Find last object:
var lastContact = Backendless.Persistence.of( Contact ).findLast();
Find object by ID:
var lastContact = Backendless.Persistence.of( Contact ).findById( objectId);
a more complete example of finding an object by ID:
var contactObject = new Contact({
name: "John",
age: 27,
phone: "1-800-MY-APPLE",
title: "Chief Fruit"
});
var contactStorage = Backendless.Persistence.of( Contact );
var myFruit = contactStorage.save( contactObject );
var contact = contactStorage.findById( myFruit[ "objectId" ] );
2.10 Advanced Search
Advanced search use-cases supported by Backendless include:
Search with query - a query is an SQL-92 expression (the where clause) referencing data object
properties.
Paged search - sets the page size and index (offset) to search from.
Sorted search - lists the data object properties to sort the result collection by.
Additionally, search requests may include special modifiers:
Request for specific properties of the data objects returned in the result collection.
Request to return related data objects attached to the 'parent' objects in the result collection.
Backendless supports the use-cases and modifiers listed above with a special class - Backendless.
DataQuery:
Backendless.DataQuery {
var properties = [];
var condition;
var options;
}
where:
properties - is an array containing property names. If the array has any data, find
operations return data object(s) with the requested property names.
condition - search condition - this is a query in the SQL-92 syntax (the "where"
clause part) to search for data with.
options - an object used to control data paging, sorting and loading of the related
data. The options object may include the following properties:
{
var pageSize;
var offset;
var sortBy;
var relations;
}
where:
pageSize - sets the size of the "page", i.e. the size of the
collection of results to be returned by the find
Data Service
2014 Backendless Corp.
37
operation.
offset - sets the offset in the data store from where to
search for data.
sortBy - is an array of the data object properties to sort
the result collection by.
relations - is an array of the related data object properties.
Each property must point to a related entity.
To run a query-based search, use the following API methods:
Method Signature:
var collectionResult = Backendless.Persistence.of( constructor-function ).
find( query, async );
Arguments:
constructor-function - a reference to a JavaScript constructor function defining a
JavaScript class which determines which table the query will
use to search for data objects.
query - an instance of Backendless.DataQuery described above.
The object contains the search query and other search
options.
async - Optional argument. If provided, the method is executed
asynchronously. The successCallback function referenced in
the async object receives a callback when the method
successfully returns a search result. If an error occurs, the
faultCallback function is invoked. See Sync and Async Calls
for additional details.
Return Value:
The synchronous invocation returns a collection of objects found by the query. The
asynchronous invocation receives the return value through a callback executed on the
AsyncCallback object.
Examples:
Consider the following class:
function Contact(args) {
args = args || {};
this.name = args.name || "";
this.age = args.age || "";
this.phone = args.phone || "";
this.title = args.title || "";
}
The following code demonstrates various search queries:
Find all contacts where the value of the "age" property equals 21:
var contactStorage = Backendless.Persistence.of( Contact );
var dataQuery = {
condition: "age = 21"
};
var myContact = contactStorage.find( dataQuery );
Find all contacts where the value of the "age" property is greater than 21:
var contactStorage = Backendless.Persistence.of( Contact );
var dataQuery = {
condition: "age > 21"
};
var myContact = contactStorage.find( dataQuery );
Backendless API for JavaScript
2014 Backendless Corp.
38
Find all contacts where the value of the "age" property is between 21 and 30:
var contactStorage = Backendless.Persistence.of( Contact );
var dataQuery = {
condition: "age >= 21 and age <= 30"
};
var myContact = contactStorage.find( dataQuery );
Find all contacts by name:
var contactStorage = Backendless.Persistence.of( Contact );
var dataQuery = {
condition: "name = 'John'"
};
var myContact = contactStorage.find( dataQuery );
Find all contacts by partial name match:
var contactStorage = Backendless.Persistence.of( Contact );
var dataQuery = {
condition: "name = '%Jo%'"
};
var myContact = contactStorage.find( dataQuery );
2.11 Related Data
Backendless Data Service supports CRUD (create, retrieve, update, delete) operations for complex
hierarchies, that is complex types, referencing other complex types. Consider the following class
diagram:
Notice the PhoneBook entity references Contact through two properties - "owner" (the one to one
relationship) and "contacts" (the one to many relationship). Each contact entity also references
Address. These entities will be used to demonstrate how Backendless handles related entities in all
basic data persistence operations. Consider the following class definitions for these entities:
function PhoneBook( args ) {
args = args || {};
this.___class = 'PhoneBook';
this.owner = args.owner || {}; // Contact
this.contacts = args.contacts || null; // collection of Contacts
}
function Contact(args) {
args = args || {};
this.___class = 'Contact';
Data Service
2014 Backendless Corp.
39
this.name = args.name || "";
this.age = args.age || "";
this.phone = args.phone || "";
this.title = args.title || "";
this.address = args.address || {};
}
function Address(args) {
args = args || {};
this.___class = 'Address';
this.street = args.street || "";
this.city = args.city || "";
this.state = args.state || "";
}
Persistence of related data objects and complex object hierarchies uses the same APIs used for the
Search, Create/Update and Delete operations.
Consider the following examples:
Save and Update Operations
Delete Operations
Find Operations
Save and Update Operations:
Constructing PhoneBook with the Owner and no Contacts:
var phoneBookStorage = Backendless.Persistence.of( PhoneBook );
var john = new Contact({
name: "John",
age: 27,
phone: "1-972-5551212",
title: "Plumber",
address: new Address({
street: "123 Main St.",
city: "Denver",
state: "Colorado"
})
});
var JohnsPhoneBook = phoneBookStorage.save( new PhoneBook({
owner: john
}));
Constructing PhoneBook with the Owner and two Contacts:
Backendless API for JavaScript
2014 Backendless Corp.
40
var phoneBookStorage = Backendless.Persistence.of( PhoneBook );
var phoneBookOwner = new Contact({
name: "John",
age: 27,
phone: "1-972-5551212",
title: "Plumber",
address: new Address({
street: "123 Main St.",
city: "Denver",
state: "Colorado"
})
});
var contact1 = new Contact({
name: "Susan",
age: 32,
phone: "1-212-1112233",
title: "VP of Marketing",
address: new Address({
street: "555 Commerce St.",
city: "New York",
state: "NY"
})
});
var contact2 = new Contact({
name: "Bobby",
age: 22,
phone: "1-415-1234567",
title: "VP of Sales",
address: new Address({
street: "1991 Baker Ln.",
city: "San Francisco",
state: "CA"
})
});
Data Service
2014 Backendless Corp.
41
var JohnsPhoneBook = phoneBookStorage.save( new PhoneBook({
owner: phoneBookOwner,
contacts: [ contact1, contact2 ]
}));
Add Contact to an existing PhoneBook (uses the "savedPhoneBook" object created at the
end of the example above):
// use the phone book object created in the previous example, for example:
var phoneBookStorage = Backendless.Persistence.of( PhoneBook );
var JohnsPhoneBook = phoneBookStorage.save( new PhoneBook({
owner: phoneBookOwner,
contacts: [ contact1, contact2 ]
}));
// create a new contact
var Mom = new Contact({
name: "Mom",
age: 50,
phone: "1-304-MY-HOME",
title: "Best Mom",
address: new Address({
street: "10715 Dexter Dr",
city: "Denver",
state: "Colorado"
Backendless API for JavaScript
2014 Backendless Corp.
42
})
});
// add the contact to the existing phone book:
JohnsPhoneBook["contacts"].push(Mom);
// save the phone book so the contact list is updated in the persistent data
store
JohnsPhoneBook = phoneBookStorage.save( JohnsPhoneBook );
Update a property in the aggregated object (update the phone number in the "owner" of
PhoneBook) and save PhoneBook:
// use any of the samples above to the point when PhoneBook is saved
// then use JohnsPhoneBook object, for example:
var phoneBookStorage = Backendless.Persistence.of( PhoneBook );
var JohnsPhoneBook = phoneBookStorage.save(new PhoneBook({
owner: John
}));
// update phone number for the phone book owner
var phoneBookOwner = JohnsPhoneBook[ "owner" ];
phoneBookOwner.[ "phone" ] = "415-5551212";
// save the phone book again
phoneBookStorage.save( JohnsPhoneBook );
Removing one contact from PhoneBook, adding another and re-saving PhoneBook:
Data Service
2014 Backendless Corp.
43
// use any of the samples above
// which save a PhoneBook with one or more contacts,
// then use JohnsPhoneBook object in this sample, for example:
var phoneBookStorage = Backendless.Persistence.of( PhoneBook );
var JohnsPhoneBook = phoneBookStorage.save(new PhoneBook({
owner: John,
contacts: [contact1, contact2];
}));
var bobby = new Contact({
name: "Bobby",
age: 21,
phone: "314-5551212",
title: "plumber",
address: new Address({
street: "123 Elm St",
city: "St. Louis",
state: "Missouri"
})
});
// remove one contact from the collection of contacts
JohnsPhoneBook["contacts"].splice(1, 1);
Backendless API for JavaScript
2014 Backendless Corp.
44
// add the new contact
JohnsPhoneBook["contacts"].push(Jack);
// save the phone book and all the changes in it
JohnsPhoneBook = phoneBookStorage.save(JohnsPhoneBook);
Delete Operations
Delete parent object (deleting a PhoneBook):
// use any of the samples above
// which save a PhoneBook with one or more contacts,
// then use JohnsPhoneBook object in this sample, for example:
var phoneBookStorage = Backendless.Persistence.of( PhoneBook );
var JohnsPhoneBook = phoneBookStorage.save(new PhoneBook({
owner: John
}));
phoneBookStorage.remove( JohnsPhoneBook );
Remove a contact from PhoneBook and save the change:
Data Service
2014 Backendless Corp.
45
// use any of the samples above
// which save a PhoneBook with one or more contacts,
// then use JohnsPhoneBook object in this sample, for example:
var phoneBookStorage = Backendless.Persistence.of( PhoneBook );
var JohnsPhoneBook = phoneBookStorage.save(new PhoneBook({
owner: John,
contacts: [contact1, contact2];
}));
// get object ID of the contact we will remove
var contactObjectId = JohnsPhoneBook["contacts"][ 0 ][ "objectId" ];
// remove a contact from the collection of contacts
JohnsPhoneBook["contacts"].splice( 1, 1 );
// save the phone book and all the changes in it. At this point the actual
// contact is not removed in the data storage, it is only disassociated from
// the phone book.
JohnsPhoneBook = phoneBookStorage.save( JohnsPhoneBook );
// now remove the contact from the data store
JohnsPhoneBook = phoneBookStorage.remove( contactObjectId );
Find Operations
Find all contacts in a city for a specific phone book:
// assume a phone book is created with one or more contacts.
// See the relevant samples above which demonstrate how that can be done
var contactStorage = Backendless.Persistence.of( Contact );
var JohnsPhoneBookID = JohnsPhoneBook[ "objectId" ].split( '.' )[0];
var query = {condition: "PhoneBook[contacts].objectId='" +
JohnsPhoneBookID + "' and address.city='Denver'"};
Backendless API for JavaScript
2014 Backendless Corp.
46
var contactsFromDenver = contactStorage.find( query );
Find all contacts for the specific phone book where the city name contains letter 'a':
// assume a phone book is created with one or more contacts.
// See the relevant samples above which demonstrate how that
// can be doneuse any of the samples above
var contactStorage = Backendless.Persistence.of( Contact );
var JohnsPhoneBookID = JohnsPhoneBook[ "objectId" ].split( '.' )[0];
var query = {condition: "PhoneBook[contacts].objectId='" +
JohnsPhoneBookID + "' and address.city like '%a%'"};
var contactsFromDenver = contactStorage.find( query );
Find all contacts where age is greater than 20 for a specific phone book:
// assume a phone book is created with one or more contacts.
// See the relevant samples above which demonstrate how that
// can be doneuse any of the samples above
var contactStorage = Backendless.Persistence.of( Contact );
var JohnsPhoneBookID = JohnsPhoneBook[ "objectId" ].split( '.' )[0];
var query = {condition: "PhoneBook[contacts].objectId='" +
JohnsPhoneBookID + "' and age > 20"};
var contactsFromDenver = contactStorage.find( query );
Find all contacts for a specific phone book where age is within the specified range:
// assume a phone book is created with one or more contacts.
// See the relevant samples above which demonstrate how that
// can be doneuse any of the samples above
var contactStorage = Backendless.Persistence.of( Contact );
var JohnsPhoneBookID = JohnsPhoneBook[ "objectId" ].split( '.' )[0];
var query = {condition: "PhoneBook[contacts].objectId='" +
JohnsPhoneBookID + "' and age >= 21 and age <= 30"};
var contactsFromDenver = contactStorage.find( query );
Find all contacts for a specific phone book where age is greater than 20 and the city is
Tokyo:
// assume a phone book is created with one or more contacts.
// See the relevant samples above which demonstrate how that
// can be doneuse any of the samples above
var contactStorage = Backendless.Persistence.of( Contact );
var JohnsPhoneBookID = JohnsPhoneBook[ "objectId" ].split( '.' )[0];
var query = {condition: "PhoneBook[contacts].objectId='" +
JohnsPhoneBookID + "' and age > 20 and address.city = 'Tokyo'"};
var contactsFromDenver = contactStorage.find( query );
Find all contacts for a specific phone book updated in the past month:
// assume a phone book is created with one or more contacts.
// See the relevant samples above which demonstrate how that
// can be done. Use any of the samples above
var contactStorage = Backendless.Persistence.of( Contact );
var JohnsPhoneBookID = JohnsPhoneBook[ "objectId" ].split( '.' )[0];
var monthAgo = new Date((new Date()).getTime() - 30 * 24 * 60 * 60 * 1000);
monthAgo = "" + monthAgo.getFullYear() +
Data Service
2014 Backendless Corp.
47
(monthAgo.getMonth() > 8 ? monthAgo.getMonth() + 1 : "0" + (monthAgo.
getMonth() + 1)) +
(monthAgo.getDate() > 9 ? monthAgo.getDate() : "0" + monthAgo.getDate());
var query = {condition: "PhoneBook[contacts].objectId='" +
JohnsPhoneBookID + "' and created > " + monthAgo + " or updated > " +
monthAgo };
var contactsFromDenver = contactStorage.find( query );
2.12 Security
Data Service supports a very flexible security mechanism for restricting access to objects stored in
Backendless. Security permissions apply to users and roles. A permission can either grant or reject an
operation for a particular asset. In the context of Data Service, the asset is an object which your app can
retrieve, update or delete. Permissions can be granted or rejected globally, where they apply to all tables
and all objects in the data store. Additionally, every table may have its own permission matrix and owner
policy a special instruction whether object owners can or cannot retrieve/update/delete the objects
they own. Finally, every object has its own Access Control List (ACL) which is a matrix of permissions
for the operations applicable specifically to the object:
The security system is multi-layered. For an API call to retrieve, update or delete object(s), the system
goes through several where each can trim the scope of the operations. The layered order of the decision
making is important and consists of the following:
1. ObjectACL for the user who makes the call
2. ObjectACL for user-defined roles assigned to the user who makes the call.
3. Table permissions for the User account
4. Table permissions for the user-defined roles
5. Owner Policy
6. ObjectACL for system roles
7. Table permissions for system-level roles
8. Global user-defined roles
9. Global system roles
Backendless API for JavaScript
2014 Backendless Corp.
48
Where:
User-defined roles roles created by the application developer
System roles roles built into Backendless (Authenticated User, NonAuthenticated User,
SocialUser, etc)
Consider the following guide which illustrates the decision making process:
1. Backend receives an API request to load data from a table (the Find operation). All objects
become candidates for the retrieval. Backendless goes through the security permissions chain
to determine which ones must be included.
2. ObjectACL for the user who makes the call. Backendless checks if there are any
restrictions for the user account at the object level. Any object in the collection with ACL which
rejects access to the user is excluded from the result. To see or modify the permissions for a
particular object, click the key icon in the ACL column in the data browser in management
console.
Data Service
2014 Backendless Corp.
49
3. ObjectACL for user-defined roles assigned to the user who makes the call. This is the
same check as the one above, except Backendless looks into the permissions for the roles
defined by the application developer. If the user belongs to any of the custom roles,
Backendless checks if these roles are allowed to perform the current operation. In the
screenshot below, only the MyRole role will be checked in this step, since this is the only
custom role in the application:
4. Table permissions for the User account. Every table in Backendless may have its own set of
permissions for users and roles. At this point Backendless checks if the currently logged in
user is allowed to run the current operation. For example, if the Find operation is denied for the
user, no objects would be returned.
5. Table permissions for the user-defined roles. This step is identical to the one described
above with the exception that is checks custom roles for the table. Since this guide reviews the
decision making process for the Find operation, Backendless checks the column for Find. If any
Backendless API for JavaScript
2014 Backendless Corp.
50
of the custom roles deny access, the operation is rejected and no data is returned.
6. Owner Policy. When a new object is created in Backendless, the system automatically links
it with the account of the currently logged in user. You can see that information in the ownerId
column in any of your tables in the data browser. With the association between objects and
users, Backendless provides a way to control whether users can get access to the data they
created. This is done through a concept we call Owner Policy. The policy is available on the
Schema and Permissions screen. Select a table in the data browser and click the Table
Schema and Permissions button in the upper right corner. Select the Owner Policy menu
item. Owner policy can be global (select All Tables from the drop down in the upper right
corner) or it could apply to a specific table.
Granting a permission for an operation in Owner Policy, guarantees that the objects owned by
the current user will be included in the resulting collection. Denying a permission, takes out the
owned objects from the collection of candidate objects to return. Consider the following:
Granting Find permission in Owner Policy:
Results in the following. The objects with bold border are guaranteed to be returned. All other
objects will be subject to the subsequent permission checks.
Data Service
2014 Backendless Corp.
51
However, if the Owner Policy rejects a permission:
The objects owned by the current user will be excluded from the resulting collection. All
remaining objects will be decided by the subsequent permission checks.
7. Object ACL for system roles. This check is identical to step 3 (Object ACL for custom roles).
The difference is the system roles cover larger groups of users. For example, this step would
make possible to restrict access to specific objects for all authenticated (or not authenticated)
Backendless API for JavaScript
2014 Backendless Corp.
52
users, yet the object would be returned with a query made by the objects owner if the Owner
Policy (previous step) grants access.
8. Table permissions for system roles. Identical to step 5, this checks if any of the system
roles reject the operation at the table level.
9. Global custom roles. Global policy applies to all tables and objects. By default all table level
permissions inherit from the global policy. You can configure in the console at: Users >
Security and Permissions. Create a new role and click it to configure the permission matrix:
3 Messaging Service
3.1 Overview
Data Messaging is an essential function of mobile and desktop applications. It can be used for a
multitude of functions including chat or private messaging, system update broadcast, maintaining game
scores, etc. The Backendless Messaging Service provides API and software infrastructure enabling
publish-subscribe message exchange pattern and mobile push notifications. The service consists of the
following core concepts: channels, publishers, subscribers and registered devices:
channel - a logical medium "carrying" the messages.
publisher - a program using the Publishing API to send messages to a channel.
subscriber - a program using the Subscription API to receive messages from a channel.
registered device - a mobile device registered with a Backendless channel to receive
push notifications.
Messaging Service
2014 Backendless Corp.
53
Publish-Subscribe Messaging
With the publish-subscribe pattern, one part of the code (or an entire application) can subscribe to
receive messages and another publishes messages. A message can be any data - Backendless
supports messages of primitive or complex data types. To enable publish-subscribe messaging,
Backendless supports the concept of a channel. Subscriptions are "attached" to a channel (or multiple
channels) and messages are published into a channel. By default Backendless sends all messages
published into a channel to all the channel's subscribers. However, a subscription can include message
filters, in this case Backendless delivers only the messages matching the filter.
Push Notifications
A message published to a channel can be tagged as a push notification, thus triggering the logic for
distributing it to the registered devices. Backendless supports push notifications for iOS, Android and
Windows Phone devices. Messages published as push notifications can target either a specific
subscriber (as a device) or a group of subscribers. Subscribers can be grouped by operating system (for
example, a message sent to all registered iOS devices) or as a collection of individual registrations. The
Backendless messaging API supports different types of push notifications - badge updates, alerts, etc.
3.2 Setup
To get access to the Backendless services, JavaScript applications must reference the backendless.js
library available in the Backendless SDK for JavaScript. Alternatively, the latest version of the library can
be loaded from the following URLs:
non-compressed library:
http://api.backendless.com/sdk/js/latest/backendless.js
compressed library:
http://api.backendless.com/sdk/js/latest/backendless.min.js
Before the JavaScript client uses any of the APIs, the code must initialize the Backendless Application
using the following call:
Backendless.initApp( application-Id, secret-key, version )
Values for the application-id and secret-key headers must be obtained through the Backendless
Console:
1. Login to your account and select the application.
2. Click the Manage icon from the vertical icon-menu on the left.
3. The "App Settings" section is selected by default. The interface contains the text fields for
"Application ID" and secret keys for each supported client-side environment.
4. Use the "Copy" button to copy the value into the system clipboard.
Backendless API for JavaScript
2014 Backendless Corp.
54
Make sure to use the "JavaScript Secret Key" for the secret-key argument.
The version argument must contain the name of the targeted version. When a new application is
created, the default version name is "v1". To manage versions, login to the console, select the
"Manage" icon and click "Versioning".
3.3 Core Classes
The Backendless Messaging Service uses the following core classes:
Backendless.Messaging - is the central point for all Backendless Messaging APIs. Provides
access to the device registration, subscription management and messaging publishing functionality
SubscriptionOptions - may be used in the subscription call to establish subscriber identity and set messaging filtering parameters.
var SubscriptionOptions = function (args) {
args = args || {};
// id uniquely identifying the subscriber in the application
this.subscriberId = args.subscriberId || undefined;
// subtopics can be used to "multiplex" message distribution over the same
channel
this.subtopic = args.subtopic || undefined;
// selector is a query in the SQL-92 format referencing message headers.
Messaging Service
2014 Backendless Corp.
55
// if a published message's headers match the query, the message is delivered
to the subscriber
this.selector = args.selector || undefined;
};
PublishOptions - this class is the publishing counterpart for the SubscriptionOptions
shown above. Can be used in the publishing API to set the publisher's ID and/or to set properties for
message filtering, such as message headers and subtopic.
var PublishOptions = function (args) {
args = args || {};
// id identifying the publisher
this.publisherId = args.publisherId || undefined;
// an untyped JS object containing key/value pairs for
// the collection of headers. Object fields represent keys,
// corresponding values are the header values
this.headers = args.headers || undefined;
// subtopic - can be used to "multiplex" messages in the same channel
this.subtopic = args.subtopic || undefined;
};
DeliveryOptions - used in the publishing API for targeted message delivery. Supported options
include: tagging a message as a push notification, scheduling message delivery in the future,
scheduling repeated message delivery and message expiration.
var DeliveryOptions = function (args) {
args = args || {};
// determines how message will be published. Possible values are:
// "ONLY" - message is published only as a push notification
// "ALSO" - message is published both as a push notification AND a pub/sub
message
// if the value is not set, message is published as a pub/sub message
this.pushPolicy = args.pushPolicy || undefined;
// this is a mask value indicating that a message must be delivered to
devices grouped by the OS
// the value can be composed of the following:
// 1 - IOS
// 2 - ANDROID
// 4 - WINDOWS PHONE
// To set a value use the bitwise OR. For example, to send a push
notification to all
// iOS and Android devices, set the value to 1 | 2.
this.pushBroadcast = args.pushBroadcast || undefined;
// can be set to an array of device IDs to send push notification to.
this.pushSinglecast = args.pushSinglecast || undefined;
// a timestamp of when the message should be published at.
this.publishAt = args.publishAt || undefined;
Backendless API for JavaScript
2014 Backendless Corp.
56
// sets an interval between the repeated message publish events. Must be a
value in milliseconds.
this.repeatEvery = args.repeatEvery || undefined;
// sets the timestamp when the repeated messaging publishing should stop
this.repeatExpiresAt = args.repeatExpiresAt || undefined;
};
3.4 Sync and Async Calls
All Backendless API methods for JavaScript can be invoked synchronously or asynchronously. The
invocation mode is determined by a special argument which (if provided) is always the last argument in
the method. When the argument is present, the method is invoked asynchronously, otherwise, the
method blocks until the return value becomes available. The argument is an instance of the
Backendless.Async class. The purpose of the class is to reference two callback functions - success
and failure. The success callback is invoked when the return value for the API call becomes available.
The failure one is called is the API method results in an error. The Backendless.Async function is
defined as:
function Async( successCallback );
function Async( successCallback, context );
function Async( successCallback, faultCallback, context );
Backendless.Async = Async;
where:
successCallback - a reference to a function which will be called when the server returns a result.
The signature of this callback function must accept one argument which will be
the actual result object returned by the server.
faultCallback - an (optional) reference to a function which will be called if the server returns an
error. The function must accept one argument which is a fault object containing
the information about the error.
context - an (optional) reference to the object which is used as "this" when calling
successCallback or faultCallback
3.5 Error Handling
When the server reports an error, it is delivered to the client through a fault object, which is an untyped
JavaScript object. The fault object has the same structure for both synchronous and asynchronous
invocations:
{
"message": value,
"statusCode": value
}
where:
message - contains a string value with the description of the error
statusCode - error code as a string value. Currently all the error codes are numbers,
however the method returning the error code returns the String type. This is
done for future expansion of the error code system which may include
Messaging Service
2014 Backendless Corp.
57
characters.
The asynchronous calls receive the fault through the fault callback referenced in the Async function.
For the synchronous calls the fault object is thrown as an error which must be handled in a catch( err
) block:
try
{
backendlessAPIcall();
}
catch( err )
{
console.log( "Error message - " + err.message );
console.log( "Error code - " + err.statusCode );
}
3.6 Message Publishing
Application can publish messages to Backendless for subsequent distribution to subscribers.
Backendless delivers published messages to subscribers as message objects and/or to devices as
push notifications. A message must be published to a channel (or a group of channels). Backendless
supports unlimited number of channels. Applications can use them as a filtering mechanism - channel
subscribers see messages published only to that channel. Similarly, devices can specify a channel (or a
group of them) when registering for push notifications. Message publishing supports the following
scenarios:
Publishing with message headers - headers is a collection of name = value pairs of arbitrary
data. Subscribers can set additional filters expressed as SQL queries which Backendless applies
to the headers. When the query matches the published data in headers, message is delivered to
the corresponding subscriber. See example.
Publishing to a subtopic - Subtopics provide an additional level of message filtering.
Multiple subtopics can be defined within a channel. Both publishes and subscribers can specify a
subtopic within a channel. Subtopic names can be defined using a multi-tiered format:
maintoken[.secondaryToken][.additionalToken]
To receive messages from more than one subtopic, subscribers can use the wildcard character (*)
in place of any tokens in the subtopic name. For instance, a subscriber could subscribe to the
following subtopic: "news..business.*", and the publisher sends messages to "news.business.
newyork" and "news.business.tokyo". In this case the messages published to either subtopic
will be delivered to the consumer.

The wildcard character in the last position will match any token in that position as well as tokens
after it. For instance, subtopic com.foo.* will match all of the following: com.foo.bar, com.foo.
abc.def, etc. However, the wildcard character in any position other than the last will match only
one token. For example, subtopic com.*.foo will match com.abc.foo and com.123.foo, but will
not match com.foo.
See example.
Publishing a message only/also as a push notification - By default Backendless delivers
published messages only to the "pub/sub subscribers", that is programs subscribed to receive
Backendless API for JavaScript
2014 Backendless Corp.
58
messages using the Subscription API. However, published messages can also be delivered as
push notifications to the registered devices. The publishing API provides a way to configure the
delivery mode for the following three modes:
API Subscribers (see example)
Only as Push Notifications (see example)
API Subscribers and Push Notifications (same example as above, see the comment in the
example's code)
Publishing a push notification to a group of devices - Backendless can deliver messages
published as a push notifications to devices grouped
by operating system. That is messages can be delivered only to Android devices, iOS or Windows
Phone or a any combination of these. See example.
Publishing a push notification and targeting specific devices - By default Backendless
delivers published messages to all matched subscribers. (Subscribers may be matched by the
topic name or a query). Alternatively, publishers can direct messages to specific subscribers by
specifying the subscriber or device ID in message meta-data. See example.
Delayed publishing - Backendless immediately processes any published messages and
delivers them to subscribers without any delay. However, publishers can specify the time when
the message should be processed. This is applicable to all the publishing options listed above.
Message processing can be canceled at any time using the message cancellation API. See
example.
Scheduled (repeated) publishing - Backendless supports repeated message processing - a
message is published once, but delivered to subscribers with the specified frequency. Repeated
delivery can stop either at the specified time or they can be canceled using the message
cancellation API. For instance, this could be used for reminders or scheduled tasks. See example
.
Method Signatures:
Backendless.Messaging.publish(channelName, message, publishOptions,
deliveryOptions, async)
where:
channelName - Name of the channel to publish the message to. If the channel does
not exist, Backendless automatically creates it.
message - Object to publish. Can be a primitive value, an array or a complex
type.
publishOptions - Optional argument. An instance of the PublishOptions class.
Contains publisher ID, message headers and subtopic name.
deliveryOptions - Optional argument. An instance of the DeliveryOptions class. May
specify message delivery policy (push, pub/sub or both), timestamp
for publishing at the specified time in the future, interval for repeated
publishing.
async - Optional argument. An instance of Backendless.Async. If present,
contains references to the success and failure callback functions.
See the Sync and Async Calls section for additional details.
Return value:
An untyped JavaScript object containing message ID and the status of the publishing
operation:
Messaging Service
2014 Backendless Corp.
59
{
status : "published" | "scheduled" | "failed",
messageId: messageIdValue
}
Errors:
The following errors may occur during the message publishing API call. See the Error Handling
section for details on how to retrieve the error code when the server returns an error:
Error
Code
Description
5003 Invalid repeatExpiresAt date in delivery options.
5007 User does not have the permission to publish messages
5030 Invalid publishAt date in the delivery options.
Examples:
Basic message publishing
Publishing with message headers
Publishing to a subtopic
Publishing a message only as a push notification
Publishing a message as a push notification and targeting specific group of devices (grouped by OS)
Publishing a push notification and targeting specific devices
Delayed publishing
Repeated publishing
Basic message publishing
Application initialization
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous publish:
var channel = "TestChannel",
message = "Hello, world!";
var response = Backendless.Messaging.publish(channel, message);
// message has been published, message status is available via response.
status
// if publish failed - the error is described in response.errorMessage
Asynchronous publish:
var channel = "TestChannel",
message = "Hello, world!",
success = function (response) {
/* ... */
},
failure = function (response) {
/* ... */
};
Backendless API for JavaScript
2014 Backendless Corp.
60
Backendless.Messaging.publish(
channel,
message,
null,
null,
new Backendless.Async(success, failure)
);
Publishing with message headers
Application initialization
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = new PublishOptions({
headers: {
city: "Denver",
state: "Colorado"
}
});
var response = Backendless.Messaging.publish(channel, message, pubOps);
// message has been published, message status is available via response.
status
// if publish failed - error is described in response.errorMessage
Asynchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = new PublishOptions({
headers: {
city: "Denver",
state: "Colorado"
}
}),
success = function (response) {
/* ... */
},
failure = function (response) {
/* ... */
};
Backendless.Messaging.publish(
channel,
message,
pubOps,
null,
new Backendless.Async(success, failure)
);
Publishing to a subtopic
Application initialization
Messaging Service
2014 Backendless Corp.
61
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = new PublishOptions({
subtopic: "sightseeing"
});
var response = Backendless.Messaging.publish( channel, message, pubOps );
// message has been published, message status is available via response.
status
// if publish failed - error is described in response.errorMessage
Asynchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = new PublishOptions({
subtopic: "sightseeing"
}),
success = function (response) {
/* ... */
},
failure = function (response) {
/* ... */
};
Backendless.Messaging.publish(
channel,
message,
pubOps,
null,
new Backendless.Async(success, failure)
);
Publishing a message only as a push notification
Application initialization
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null,
deliveryOps = new DeliveryOptions({
pushPolicy: "PUSHONLY"
});
var response = Backendless.Messaging.publish( channel, message, pubOps,
deliveryOps );
// message has been published, message status is available via response.
status
// if publish failed - error is described in response.errorMessage
Asynchronous Publish:
Backendless API for JavaScript
2014 Backendless Corp.
62
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null,
deliveryOps = new DeliveryOptions({
pushPolicy: "PUSHONLY"
}),
success = function (response) {
/* ... */
},
failure = function (response) {
/* ... */
};
Backendless.Messaging.publish(
channel,
message,
pubOps,
deliveryOps,
new Backendless.Async(success, failure)
);
Publishing a message as a push notification and
targeting specific group of devices
The only difference between this example and the one above is the value of the pushBroadcast
property in DeliveryOptions:
Application initialization
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null,
deliveryOps = new DeliveryOptions({
pushPolicy: "PUSHONLY",
pushBroadcast: "ANDROID"
});
var response = Backendless.Messaging.publish( channel, message, pubOps,
deliveryOps );
// message has been published, message status is available via response.
status
// if publish failed - error is described in response.errorMessage
Asynchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null,
deliveryOps = new DeliveryOptions({
pushPolicy: "PUSHONLY",
pushBroadcast: "ANDROID"
}),
success = function (response) {
/* ... */
},
Messaging Service
2014 Backendless Corp.
63
failure = function (response) {
/* ... */
};
Backendless.Messaging.publish(
channel,
message,
pubOps,
deliveryOps,
new Backendless.Async(success, failure)
);
Publishing a push notification and targeting specific
devices
Application initialization
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null,
deliveryOps = new DeliveryOptions({
pushPolicy: "PUSHONLY",
pushSinglecast: ["dummyDeviceId_001", "dummyDeviceId_002"] //
devices IDs
});
var response = Backendless.Messaging.publish( channel, message, pubOps,
deliveryOps );
// message has been published, message status is available via response.
status
// if publish failed - error is described in response.errorMessage
Asynchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null,
deliveryOps = new DeliveryOptions({
pushPolicy: "PUSHONLY",
pushSinglecast: ["dummyDeviceId_001", "dummyDeviceId_002"] //
devices IDs
}),
success = function (response) {
/* ... */
},
failure = function (response) {
/* ... */
};
Backendless.Messaging.publish(
channel,
message,
pubOps,
deliveryOps,
new Backendless.Async(success, failure)
Backendless API for JavaScript
2014 Backendless Corp.
64
);
Delayed publishing
Application initialization
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null,
deliveryOps = new DeliveryOptions({
publishAt: (new Date()).getTime() + 60 * 1000 // 1 minute delay
});
var response = Backendless.Messaging.publish( channel, message, pubOps,
deliveryOps );
// message has been published, message status is available via response.
status
// if publish failed - error is described in response.errorMessage
Asynchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null,
deliveryOps = new DeliveryOptions({
publishAt: (new Date()).getTime() + 60 * 1000 // 1 minute delay
}),
success = function (response) {
/* ... */
},
failure = function (response) {
/* ... */
};
Backendless.Messaging.publish(
channel,
message,
pubOps,
deliveryOps,
new Backendless.Async(success, failure)
);
Repeated publishing
Application initialization
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null,
Messaging Service
2014 Backendless Corp.
65
deliveryOps = new DeliveryOptions({
repeatEvery: 10, // frequency in seconds
repeatExpiresAt: (new Date()).getTime() + 60 * 1000 // expiration
timestamp, eg: after 1 minute
});
var response = Backendless.Messaging.publish( channel, message, pubOps,
deliveryOps );
// message has been published, message status is available via response.
status
// if publish failed - error is described in response.errorMessage
Asynchronous Publish:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null;
deliveryOps = new DeliveryOptions({
repeatEvery: 10, // frequency in seconds
repeatExpiresAt: (new Date()).getTime() + 60 * 1000 // expiration
timestamp, eg: after 1 minute
}),
success = function (response) {
/* ... */
},
failure = function (response) {
/* ... */
};
Backendless.Messaging.publish(
channel,
message,
pubOps,
deliveryOps,
new Backendless.Async(success, failure)
);
3.7 Publish Push Notifications
Publishing a push notification is a specialized usage of the Message Publishing API. Push notifications
have different graphical representation on different mobile operating systems. For instance, a push
notification on an iOS device may be either an alert or a badge update, however a notification on a
Windows Phone device may be either a toaster alert or a tile element update. Backendless supports
different formats of the push notification delivery to various operating systems via specialized message
headers. These headers must be added to the publish options object or in case of REST clients, they
are plain message headers:
Operating
System
Headers Description
iOS
"ios-alert":value
Sets the text of
the alert
message. If the
header is not
present and the
published
notification
targets the iOS
devices,
Backendless
Backendless API for JavaScript
2014 Backendless Corp.
66
sets the header
to the value of
the "message"
argument. To
disable this
behavior, set
the ios-alert
header to null.
"ios-badge":value
Sets the value
to update the
badge with
"ios-sound":URL string or array of bytes
Sets either a
URL for the
sound
notification to
play on the
device or an
array of bytes
for the sound to
play.
Android
"android-ticker-text":value
Sets the text of
the ticker
showing up at
the top of a
device's screen
when the device
receives the
notification.
"android-content-title":value
Sets the title of
the notification
as it is visible in
the Android
Notification
Center
"android-content-text":value
Sets the
message of the
notification
which appears
under android-
content-title
in the Android
Notification
Center.
Windows
Phone
"wp-title":value,
"wp-content":value
Sets the title
and the content
of a toast
notification.
Messaging Service
2014 Backendless Corp.
67
"wp-type":"TILE":
"wp-title" : value,
"wp-backgroundImage" : URL string,
"wp-badge" : number value,
"wp-backTitle" : value,
"wp-backImage" : URL string,
"wp-backContent" : value
Sets the
properties for a
tile notification.
"wp-type":"RAW",
"wp-raw":XMLString
Sets the
properties for a
raw notification
Push notifications can be published directly from Backendless Console or using the API (see the
examples in the Message Publishing section).
3.8 Cancel Scheduled Message
Delayed or scheduled messages can be canceled using the API documented below. Backendless
processes delayed messages at the time specified by the publisher. Scheduled messages are
processed and delivered with a specified interval.
Method Signatures:
Backendless.Messaging.cancel(messageId, async)
where:
messageId - ID of the message to cancel.
async - Optional argument. An instance of Backendless.Async. If present,
contains references to the success and failure callback functions.
See the Sync and Async Calls section for additional details.
Return value:
true if the scheduled message has been successfully canceled, false otherwise.
Errors:
The following errors may occur during the message cancellation API call. See the Error Handling
section for details on how to retrieve the error code when the server returns an error:
Error
Code
Description
5040 Message has already been canceled or does not exist.
Examples:
Application initialization
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous Publish then Cancel:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null;
deliveryOps = new DeliveryOptions({
Backendless API for JavaScript
2014 Backendless Corp.
68
publishAt: (new Date()).getTime() + 60 * 1000 // 1 minute delay
});
var response = Backendless.Messaging.publish( channel, message, pubOps,
deliveryOps );
Backendless.Messaging.cancel(response.messageId);
Asynchronous Publish then Cancel:
var channel = "TestChannel",
message = "Hello, world!",
pubOps = null;
deliveryOps = new DeliveryOptions({
publishAt: (new Date()).getTime() + 60 * 1000 // 1 minute delay
}),
success = function (response) {
/* ... */
},
failure = function (response) {
/* ... */
};
Backendless.Messaging.publish(
channel,
message,
pubOps,
deliveryOps,
new Backendless.Async(success, failure)
);
var cancelSuccess = function (response) {
/* ... */
},
cancelFailure = function (response) {
/* ... */
};
Backendless.Messaging.cancel(response.messageId,
new Backendless.Async(cancelSuccess,
cancelFailure))
3.9 Message Subscription
In order to receive published messages, application must subscribe to a channel using the API below.
Using the API, an application becomes an "API subscriber". Another form of subscription can be
accomplished by using the Device Registration API which provides a way to receive push notifications.
Note that the same mobile application can use both device registration and message subscription APIs.
Method Signatures:
Backendless.Messaging.subscribe(channelName, subscriptionCallback,
subscriptionOptions, async)
where:
channelName - ID of the message to cancel.
subscriptionCallback - A callback function where the messaging system delivers
published messages for the subscription.
subscriptionOptions - Optional argument. An instance of SubscriptionOptions
which can be used to set subscriber ID, subtopic or selector.
See the Message Filtering section for additional details.
async - Optional argument. An instance of Backendless.Async. If
Messaging Service
2014 Backendless Corp.
69
present, contains references to the success and failure
callback functions. See the Sync and Async Calls section for
additional details.
Return value:
An object identifying the subscription. Should be used to cancel subscription.
Errors:
The following errors may occur during the message cancellation API call. See the Error Handling
section for details on how to retrieve the error code when the server returns an error:
Error
Code
Description
5008 User does not have permission to create a subscription.
5009 General subscription error. See error message for additional details.
5010 Unknown messaging channel.
Receiving Messages
The JavaScript clients retrieve messages from Backendless using short polling. The
subscriptionCallback function in the subscribe call receives published messages. The
function's argument is an untyped object with the "messages" property. The property contains an
array of messages published to the channel since the previous polling request.
var subscriptionCallback = function (data) {
var messagesArray = data["messages"];
// process messages here
}
Each message object in the array has the following structure:
{
var messageId; // ID of the message
var headers; // untyped JS object containing message headers
var data; // actual message object published by the publisher
var publisherId; // publisher ID
var timestamp; // timestamp when the message was published
}
where:
messageId - unique message ID. The ID is assigned at the time of message publishing.
headers - an associative array which is a collection of key/value pairs. Includes all the
headers included with the message publishing. Additionally, Backendless adds
the following headers: BL_APPLICATION_ID - contains the ID of the application
and BL_VERSION_URL_PREFIX - contains the name of the version of the
application.
data - message payload. It is the object sent by a publisher.
publisherID - the property contains sender (publisher) ID if it is provided by the publisher.
timestamp - a timestamp indicating when the message was received by Backendless from
the publisher.
Examples:
Application initialization
Backendless API for JavaScript
2014 Backendless Corp.
70
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous Subscribe:
var channel = "TestChannel",
callback = function (data) {
var messagesArray = data["messages"];
},
subOps = new SubscriptionOptions({ // all fields are optional
subscriberId: "myDummyID", // string value identifying subscriber
subtopic: "general", // string value - name of the subtopic
to subscribe to
"selector-query": "<value>" // string query in the SQL-92 format
(the where clause)
});
var subscription = Backendless.Messaging.subscribe(channel, callback,
subOps);
// subscription contains subscriptionId (obtain it via subscription.
subscriptionId)
Asynchronous Subscribe:
var channel = "TestChannel",
subOps = new SubscriptionOptions({ // all fields are optional
subscriberId: "myDummyID", // string value identifying subscriber
subtopic: "general", // string value - name of the subtopic
to subscribe to
"selector-query": "<value>" // string query in the SQL-92 format
(the where clause)
}),
callback = function (data) {
var messagesArray = data["messages"];
},
success = function (subscription) {
/* ... */
},
failure = function (response) {
/* ... */
};
Backendless.Messaging.subscribe(
channel,
callback,
subOps,
new Backendless.Async(success, failure)
);
Message Filtering
Backendless message filtering is a powerful mechanism enabling conditional message delivery, interest-
based subscriptions and private messaging. A subscription request may include filters in the form of
subtopics and selectors. Backendless applies subscriber's filters to every message published into the
channel and they match, the message is delivered to the subscriber.
Subtopics
Messaging Service
2014 Backendless Corp.
71
Multiple subtopics can be defined within a channel. Both publishes and subscribers can specify a
subtopic within a channel. Subtopic names can be defined using a multi-tiered format:
maintoken[.secondaryToken][.additionalToken]
To receive messages from more than one subtopic, subscribers can use the wildcard character (*) in
place of any tokens in the subtopic name. For instance, a subscriber could subscribe to the following
subtopic: "news..business.*", and the publisher sends messages to "news.business.newyork" and "
news.business.tokyo". In this case the messages published to either subtopic will be delivered to the
consumer.

The wildcard character in the last position will match any token in that position as well as tokens after it.
For instance, subtopic com.foo.* will match all of the following: com.foo.bar, com.foo.abc.def, etc.
However, the wildcard character in any position other than the last will match only one token. For
example, subtopic com.*.foo will match com.abc.foo and com.123.foo, but will not match com.foo.
Selectors
A selector is a query expressed using the SQL-92 syntax and formatted as the condition part of the
SQL's WHERE clause. A query condition must reference the headers of the published messages. When
a message is published and a subscriber has a selector query, Backendless executes the query on the
headers of the published message. If the result of the query is true, the message is delivered to the
subscriber. Consider the following example where the subscriber will receive only messages containing
the "city" header with the value of "Tokyo":
Publisher:
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
var channel = "TestChannel",
weather = { temperature:70, humidity:80 },
headers = { city: "Tokyo" },
pubOps = new PublishOptions( headers );
var response = Backendless.Messaging.publish(channel, message, pubOps);
Subscriber:
// Application initialization
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
var channel = "TestChannel",
callback = function (data) {
var messagesArray = data["messages"];
},
subOps = new SubscriptionOptions({ // all fields are optional
subscriberId: "mySubscriberID", // string value identifying
subscriber
subtopic: "general", // string value - name of the subtopic
to subscribe to
selector: "city = 'Tokyo'" // string query in the SQL-92 format
Backendless API for JavaScript
2014 Backendless Corp.
72
(the where clause)
});
var subscription = Backendless.Messaging.subscribe(channel, callback,
subOps);
// subscription contains subscriptionId (obtain it via subscription.
subscriptionId)
3.10 Cancel Subscription
In order to stop a client from polling for messages, it must issue subscription cancellation request using
the API method described below:
Method Signatures:
subscriptionObject.cancelSubscription()
where:
subscriptionObject - object received as a result of the subscribe operation.
Examples:
Application initialization
var APPLICATION_ID = "<your application ID>",
SECRET_KEY = "<your secret key>",
VERSION = "v1"; //default application version;
Backendless.initApp(APPLICATION_ID, SECRET_KEY, VERSION);
Synchronous Subscribe and Cancel:
var callback = function (data) {
var messagesArray = data["messages"];
};
var subscription = Backendless.Messaging.subscribe('TestChannel', callback);
setTimeout(function () {
subscription.cancelSubscription(); // cancelling subscription after 7
seconds timeout
}, 7000);
Asynchronous Subscribe and Cancel:
var channel = "TestChannel",
subOps = new SubscriptionOptions({ // all fields are optional
subscriberId: "myDummyID", // string value identifying subscriber
subtopic: "general", // string value - name of the subtopic
to subscribe to
selector: "<value>" // string query in the SQL-92 format (the
where clause)
}),
callback = function (data) {
var messagesArray = data["messages"];
},
success = function (subscription) {
setTimeout(function () {
subscription.cancelSubscription(); // cancelling subscription after
7 seconds timeout
}, 7000);
Messaging Service
2014 Backendless Corp.
73
},
failure = function (response) {
/* ... */
};
Backendless.Messaging.subscribe(
channel,
callback,
subOps,
new Backendless.Async(success, failure)
);
4 File Service
4.1 Overview
Every Backendless backend/app is allocated a dedicated file storage space. The file storage is located
remotely on the Backendless servers. The file storage can be used to store application's files and on-
demand video streams. Backendless File Service provides the API to work with the file storage. The API
supports the following operations:
File Upload - upload files to the applications's file storage. The operation creates directories up
the hierarchy if necessary. Returns file URL which can be used to download or share the file
with others.
File Download - download file using file's URL. The download operation is subject to the
permissions from the File access control list (ACL).
File Deletion - delete a file from the file storage. The delete operation is subject to the
permissions from the File access control list (ACL).
Directory Deletion - same as file deletion, but applies to the directories.
File/Directory Security (File ACL) - assign/unassign user and roles permissions to upload,
download and delete files and directories. This API is used to modify file or directory ACL.
In addition to the API implementation, the File Service enables the following capabilities:
Git Integration - application developers can interact with the file storage as with a git repository.
Web Hosting - file storage can be used to host static web content.
Custom Domain Name - a custom domain name can be mapped to the file storage in a
Backendless backend. This feature in combination with the Web Hosting provides a way to host
websites on Backendless.
Custom Web Templates Hosting - includes HTML files and JS scripts for special pages used in
various workflows such as user email confirmation, password change and session expiration.
4.2 Setup
To get access to the Backendless services, JavaScript applications must reference the backendless.js
library available in the Backendless SDK for JavaScript. Alternatively, the latest version of the library can
be loaded from the following URLs:
non-compressed library:
http://api.backendless.com/sdk/js/latest/backendless.js
compressed library:
Backendless API for JavaScript
2014 Backendless Corp.
74
http://api.backendless.com/sdk/js/latest/backendless.min.js
Before the JavaScript client uses any of the APIs, the code must initialize the Backendless Application
using the following call:
Backendless.initApp( application-Id, secret-key, version )
Values for the application-id and secret-key headers must be obtained through the Backendless
Console:
1. Login to your account and select the application.
2. Click the Manage icon from the vertical icon-menu on the left.
3. The "App Settings" section is selected by default. The interface contains the text fields for
"Application ID" and secret keys for each supported client-side environment.
4. Use the "Copy" button to copy the value into the system clipboard.
Make sure to use the "JavaScript Secret Key" for the secret-key argument.
The version argument must contain the name of the targeted version. When a new application is
created, the default version name is "v1". To manage versions, login to the console, select the
"Manage" icon and click "Versioning".
4.3 Sync and Async Calls
All Backendless API methods for JavaScript can be invoked synchronously or asynchronously. The
invocation mode is determined by a special argument which (if provided) is always the last argument in
File Service
2014 Backendless Corp.
75
the method. When the argument is present, the method is invoked asynchronously, otherwise, the
method blocks until the return value becomes available. The argument is an instance of the
Backendless.Async class. The purpose of the class is to reference two callback functions - success
and failure. The success callback is invoked when the return value for the API call becomes available.
The failure one is called is the API method results in an error. The Backendless.Async function is
defined as:
function Async( successCallback );
function Async( successCallback, context );
function Async( successCallback, faultCallback, context );
Backendless.Async = Async;
where:
successCallback - a reference to a function which will be called when the server returns a result.
The signature of this callback function must accept one argument which will be
the actual result object returned by the server.
faultCallback - an (optional) reference to a function which will be called if the server returns an
error. The function must accept one argument which is a fault object containing
the information about the error.
context - an (optional) reference to the object which is used as "this" when calling
successCallback or faultCallback
4.4 Error Handling
When the server reports an error, it is delivered to the client through a fault object, which is an untyped
JavaScript object. The fault object has the same structure for both synchronous and asynchronous
invocations:
{
"message": value,
"statusCode": value
}
where:
message - contains a string value with the description of the error
statusCode - error code as a string value. Currently all the error codes are numbers,
however the method returning the error code returns the String type. This is
done for future expansion of the error code system which may include
characters.
The asynchronous calls receive the fault through the fault callback referenced in the Async function.
For the synchronous calls the fault object is thrown as an error which must be handled in a catch( err
) block:
try
{
backendlessAPIcall();
}
catch( err )
{
console.log( "Error message - " + err.message );
console.log( "Error code - " + err.statusCode );
}
Backendless API for JavaScript
2014 Backendless Corp.
76
4.5 File Upload
The file upload operation delivers and saves a local file in the remote Backendless file storage. The return
value of the operation is the file URL which has the following structure:
https://api.backendless.com/<application id>/<version name>/files/
<path>/<file name>
where:
<application id> - ID of the application which can be obtained from the Manage > App
Settings screen of the Backendless Console
<version name> - Application's version name
<path> - Directory path where the file is saved
<file name> - Name of the file
The URL assigned to a file and returned as a result of the upload operation accounts for any security
permissions assigned to the file (or the folder it is located in).
Backendless Console includes a file browser with the management functions to upload files, create or
delete directories and files. The file browser is available in the Files section of the console:
File browser also provides a way to see the contents of the files. Every file is a link which opens the file.
The URL of files in file browser is not the same as the URL returned by the file upload operation. The
reason file browser uses a different URL is to let the application developer see the file contents without
any application security constraints. The only constraint applied to the URLs available in file browser is
the application developer must be logged to the console.
Methods:
Backendless.Files.upload( file, path, async )
Backendless.Files.upload( files, path, async )
Arguments:
file - an instance of JavaScript File class.
files - an instance of JavaScript FileList class.
File Service
2014 Backendless Corp.
77
path - Directory path (without the name of the file) in the
Backendless file storage where the file should be stored. If the
path does not exist, Backendless File Service creates the
directory structure.
async - Asynchronous operation handler. Must contain references to
"success" and "failure" callback functions. The "success"
function receives a callback when the method successfully
uploads file(s). If an error occurs, the faultCallback function is
invoked. See Sync and Async Calls for additional details.
Return Value:
The return value, which is the URL of the uploaded file, is delivered through a callback referenced
on the Async object.
Example:
HTML:
<input type="file" id="files" name="files[]" multiple />
<input type="button" onclick="uploadFileFunc(); return false;" value="Upload
File"/>
JavaScript:
// this line goes into the app initialization block
document.getElementById('files').addEventListener('change',
handleFileSelect, false);
function handleFileSelect(evt)
{
files = evt.target.files; // FileList object
}
function uploadFileFunc()
{
var callback = {};
callback.success = function(result)
{
alert( "File successfully uploaded. Path to download: " + result.
fileURL );
}
callback.fault = function(result)
{
alert( "error - " + result.message );
}
Backendless.Files.upload( files, "my-folder", callback );
}
4.6 File Download
Downloading a file from the Backendless file storage is the basic HTTP GET operation. The operation
should use the same URL which Backendless returned as the result of the file upload operation.
Alternatively, if the file was uploaded manually using the console, the URL can be composed as:
Backendless API for JavaScript
2014 Backendless Corp.
78
https://api.backendless.com/<application id>/<version name>/files/
<path>/<file name>
where:
<application id> - ID of the application which can be obtained from the Manage > App
Settings screen of the Backendless Console.
<version name> - Application's version name.
<path> - Directory path where the file is saved.
<file name> - Name of the file.
Files fetched with the URL scheme defined above are subject to the security constraints and
permissions established by the application developer. See the Files Security section for additional
details on how to secure file storage. Fetching a file secured by an access control list (ACL) policy
requires an additional HTTP header in the request:
user-token:<value>
where:
<value> - Value of the user token established for the current user session as a
result of the user login operation. The token uniquely identifies the user
session. It is used by Backendless to establish user identity for all
operations where the token is present. This is necessary in order to
determine permissions applicable to the user and the roles associated
with the account.
4.7 File Deletion
To delete a file from the Backendless file storage, it must be identified by the file path/name. Files in the
Backendless storage have the following URL structure:
https://api.backendless.com/<application id>/<version name>/files/
<path>/<file name>
The API to delete a file uses the <path>/<filename> part to identify the file which must be deleted.
Methods:
Backendless.Files.remove( filePath, async )
Arguments:
filePath - Path of the file to delete. The path must consist of the file
path and file name.
async - Asynchronous operation handler. Must contain references to
"success" and "failure" callback functions. The "success"
function receives a callback when the method successfully
deletes the file. If an error occurs, the faultCallback function is
invoked. See Sync and Async Calls for additional details.
Return Value:
None. If an error occurs, it is delivered to the faultCallback function referenced in the Async
object.
Example:
File Service
2014 Backendless Corp.
79
var callback = new Backendless.Async(
function(result)
{
alert( "File successfully deleted" );
},
function(result)
{
alert( "error - " + result.message );
});
Backendless.Files.remove( "my-folder/myfile.txt", callback );
4.8 Directory Deletion
To delete a directory from the Backendless file storage, it must be identified by the its path. Directories
in the Backendless storage have the following URL structure:
https://api.backendless.com/<application id>/<version name>/files/
<path>
The API to delete a directory uses the <path> element from the URL above.
Methods:
Backendless.Files.removeDirectory( path, async )
Arguments:
path - Path of the directory to delete.
async - Asynchronous operation handler. Must contain references to
"success" and "failure" callback functions. The "success"
function receives a callback when the method successfully
deletes the directory. If an error occurs, the faultCallback
function is invoked. See Sync and Async Calls for additional
details.
Return Value:
None. If an error occurs, it is delivered to the faultCallback function referenced in the Async
object.
Example:
var callback = new Backendless.Async(
function(result)
{
alert( "Directory successfully deleted" );
},
function(result)
{
alert( "error - " + result.message );
});
Backendless.Files.remove( "my-folder/pics", callback );
Backendless API for JavaScript
2014 Backendless Corp.
80
4.9 Git Integration
Backendless file storage can also function as a git repository. This could be very convenient for
deploying multiple files from the developer's computer with a single command. Git integration is disabled
by default. To enable git for the file storage:
1. Open Backendless Console
2. Select your app/backend
3. Click Manage and scroll to the "Enable .git support" section
4. Use the toggle to turn git integration on or off:
When git integration is turned on, all files present in the file storage are immediately committed to the
repository. When git integration is being turned off, the git repository is deleted with all the associated
history (the files remain in the file storage).
When enabled, the repository is available at the following address:
https://git.backendless.com/<application id>/.git
where:
<application id> - Application ID available in Backendless Console at Manage > App
Settings.
When the Backendless backend is configured with a custom domain name, the repository URL is:
http://<custom domain name>/.git
The repository uses the same authentication as Backendless Console. That means all git commands
must use the same developer email address and password as for logging in to Backendless Console.
When a file is uploaded to file storage either via the Upload API or with the File Browser, it is
automatically committed to the repository. Likewise, when a file is pushed into the repository, it
becomes available and visible in the file storage.
It is important to note that any system level files created by git are also placed into the file storage (the .
git directory). These files are accounted for when calculating the file space used by the app/backend.
4.10 Web Hosting
Backendless file storage includes a special directory which facilitates web hosting for the app/backend.
The directory name is /web:
File Service
2014 Backendless Corp.
81
The /web folder serves as the web server root. The web server is available at the following URLs:
With custom domain name enabled for the account:
http://custom domain name
Without custom domain name:
https://api.backendless.com/<application id>/<version name>/files/
web
where:
<application id> - ID of the application which can be obtained from the Manage > App
Settings screen of the Backendless Console
<version name> - Application's version name
4.11 Custom Domain Name
Backendless File Service supports mapping of a custom domain name to the application's backend. As
a result, once a domain name is mapped, the following backend's resources become available via the
custom URL:
Service API endpoint. The default endpoint for all Backendless services is:
https://api.backendless.com
With a custom domain name, the endpoint is also available at:
http://<custom domain name>/api
Web Hosting. Backendless file storage contains a special directory - /web, which serves as the
web site root. When a custom domain name is mapped to a Backendless application/backend,
the contents of the /web directory are served for the HTTP requests with the domain name. See
Backendless API for JavaScript
2014 Backendless Corp.
82
the Web Hosting section for additional details.
git endpoint. When the Backendless git integration is enabled, the git endpoint with a custom
domain name is:
http://<custom domain name>/.git
Before a custom domain name is assigned to a Backendless application:
1. Create a CNAME record for the domain name and map it to backendless.com.
2. Open Backendless Console and select your application/backend.
3. Click Manage and scroll down to the "Custom Domain" section.
4. Enter the domain name into the text field and click Save
The Custom Domain mapping is a feature included into Backendless Plus package. The package
enables multiple features for a flat monthly subscription fee. Backendless Plus can be enabled in
console at Manage > Billing.
4.12 Custom Web Template Hosting
A client-to-backend workflow may include interaction with web pages presented to the users of the
application. Consider the following scenarios:
User registration. When a user registers with an application, he receives an email with a link to a
page. Clicking the link acknowledges that the email address is valid and the user account is
confirmed.
Password change. When a user requests password change (or password recovery), an email is
sent to the user with a link to a web page where they can reset the password.
Session expiration. When a user session with the application expires, he is redirected to a
webpage.
All these use cases have something in common - they all force the user to interact with a web page. The
Backendless Plus package allows to customize the look and feel of these pages. Once Backendless
Plus is enabled (use the Manage > Billing section in console to turn it on), Backendless puts the
templates for these pages into the /web/templates path of the backend's file storage:
File Service
2014 Backendless Corp.
83
The default style of these pages is neutral:
Registration confirmation page:
Password change page:
Backendless API for JavaScript
2014 Backendless Corp.
84
Session expiration page:
The look and feel as well as the logic in the pages can be customized by modifying the HTML/CSS /JS
files provided for each template. For example, the contents of the change_password folder is:
File Service
2014 Backendless Corp.
85
4.13 Files Security
Access to files and directories can be restricted using permissions. Backendless supports the following
permissions for files and directories:
Read - permission to load file by a URL. When applies to a directory, grants or restricts access to
the files contained therein.
Write - permission to upload a file or modify a directory by uploading files into it.
Remove - permission to delete a file or a directory.
To modify the permission matrix for a file or a directory, click the "Edit Permissions" link in file browser
in console. The permission assignment screen contains allows to work with permissions for specific
user accounts or for application roles.
To assign permissions to a user account, type in userid in the "enter user name" field, select the user(s)
and click "Add":
Backendless API for JavaScript
2014 Backendless Corp.
86
To modify a permission for an operation for a user, click the icon in the corresponding column. The icon
has 3 states:
- inherit GRANT permission from the global permission matrix. This is the default permission.
- explicit GRANT of the permission for the operation. Allows the user to perform the operation.
- DENY permission for the operation. Restricts the user from performing the operation.
Managing permissions for roles is identical to users, except all roles are automatically listed in the table:
5 Geo Service
5.1 Overview
Backendless Geolocation Service is a system supporting management and search of geo points. A geo
point in the most primitive format consists of a pair of coordinates: latitude and longitude. Optionally a
geo point may contain metadata, which is a collection of arbitrary key/value pairs. A geo point belongs
to a category, which is a logical grouping of geo points. The diagram bellow illustrates these concepts:
Backendless allows infinite number of geo points managed for an application. Geo points can be added
via an API call or the import functionality in Backendless console. Once the backend is populated with
geo points, the search API can be used to run the following types of geo queries:
Radius-based search - Searches for geo points in a circular map area defined by the coordinates
of the central point and a radius. Backendless returns all geo points within the area.
Geo Service
2014 Backendless Corp.
87
Search in a rectangular map area - Searches for geo points in a rectangular map area identified by
the coordinates of two corners defining the area (North West and South East):
Additionally, the geo search API supports the following search options available in the APIs:
Filtering by categories - Both types of search (radius-based and rectangular) can specify the
categories in which the backend should search for the geo points.
Query-based search - The metadata associated with the geo points can be used in queries
which should be formatted using the SQL-92 syntax. For example, the geo point shown in the
image above can be discovered with the following queries:
cuisine = 'French'
cuisine LIKE 'Fr%' and Atmosphere = 'Casual'
cuisine = 'French' and (Price = '$$$$' or Price = '$$$')
Relative search - Runs a search for a subset of metadata key/value pairs to match up to the
specified threshold value. The threshold must be expressed as a percentage of matches.
Backendless API for JavaScript
2014 Backendless Corp.
88
5.2 Setup
To get access to the Backendless services, JavaScript applications must reference the backendless.js
library available in the Backendless SDK for JavaScript. Alternatively, the latest version of the library can
be loaded from the following URLs:
non-compressed library:
http://api.backendless.com/sdk/js/latest/backendless.js
compressed library:
http://api.backendless.com/sdk/js/latest/backendless.min.js
Before the JavaScript client uses any of the APIs, the code must initialize the Backendless Application
using the following call:
Backendless.initApp( application-Id, secret-key, version )
Values for the application-id and secret-key headers must be obtained through the Backendless
Console:
1. Login to your account and select the application.
2. Click the Manage icon from the vertical icon-menu on the left.
3. The "App Settings" section is selected by default. The interface contains the text fields for
"Application ID" and secret keys for each supported client-side environment.
4. Use the "Copy" button to copy the value into the system clipboard.
Geo Service
2014 Backendless Corp.
89
Make sure to use the "JavaScript Secret Key" for the secret-key argument.
The version argument must contain the name of the targeted version. When a new application is
created, the default version name is "v1". To manage versions, login to the console, select the
"Manage" icon and click "Versioning".
5.3 Error Handling
When the server reports an error, it is delivered to the client through a fault object, which is an untyped
JavaScript object. The fault object has the same structure for both synchronous and asynchronous
invocations:
{
"message": value,
"statusCode": value
}
where:
message - contains a string value with the description of the error
statusCode - error code as a string value. Currently all the error codes are numbers,
however the method returning the error code returns the String type. This is
done for future expansion of the error code system which may include
characters.
The asynchronous calls receive the fault through the fault callback referenced in the Async function.
Backendless API for JavaScript
2014 Backendless Corp.
90
For the synchronous calls the fault object is thrown as an error which must be handled in a catch( err
) block:
try
{
backendlessAPIcall();
}
catch( err )
{
console.log( "Error message - " + err.message );
console.log( "Error code - " + err.statusCode );
}
5.4 Adding a Geo Category
This API creates a geo category. A geo category is a logical grouping of geo points. Category name
may contain the following literals: a-z, A-Z, numbers 0-9 and the underscore (_ ) character. The name
must start with a literal. Category names can be inspected using Backendless Console (see the image
below) or using the API call retrieving a list of categories.
Adding Categories in Console
Backendless Console supports adding a category via the graphical interface. To create a category:
1. Login to Backendless Console
2. Select your app/backend.
3. Click the Geolocation icon in the menu on the left.
4. Use the "plus" icon in the section containing the list of categories:
Geo Service
2014 Backendless Corp.
91
5. Enter the category name in the popup and click "Save".
The image below shows the Geolocation screen with categories in the app:
Backendless API for JavaScript
2014 Backendless Corp.
92
Adding Categories with the API
Methods:
Backendless.Geo.addCategory( name, async )
Arguments:
name - Name of the category to create.
async - Asynchronous operation handler. Must contain references to
"success" and "failure" callback functions. The "success"
function receives a callback when the method successfully
creates the category. If an error occurs, the faultCallback
function is invoked. See Sync and Async Calls for additional
details.
Return Value:
A javaScript object with the following structure:
{
"objectId": "<categoryId>",
"size": "0",
"name": "<categoryName>"
}
where:
Geo Service
2014 Backendless Corp.
93
<categoryId> - Internal ID assigned to the category.
<categoryName> - Name of the category created with the request.
If an error occurs, it is delivered to the faultCallback function referenced in the Async object.
Example:
var callback = new Backendless.Async(
function(result)
{
alert( "category created - " + result.name );
},
function(result)
{
alert( "error - " + result.message );
});
Backendless.Geo.addCategory( "mycategory", callback );
5.5 Deleting a Geo Category
This API deletes a geo category. If the category does not exist, the service returns an error.
Removing Categories in Console
Backendless Console supports category deletion via the graphical interface. To delete a category:
1. Login to Backendless Console
2. Select your app/backend.
3. Click the Geolocation icon in the menu on the left.
4. Use the "minus" icon in the section containing the list of categories:
Backendless API for JavaScript
2014 Backendless Corp.
94
5. Select 'Yes' in the confirmation popup.
Deleting Categories with the API
Methods:
Backendless.Geo.deleteCategory( name, async )
Arguments:
name - Name of the category to delete.
async - Asynchronous operation handler. Must contain references to
"success" and "failure" callback functions. The "success" function
receives a callback when the method successfully deletes the
category. If an error occurs, the faultCallback function is invoked.
See Sync and Async Calls for additional details.
Geo Service
2014 Backendless Corp.
95
Return Value:
true if the category is deleted, false otherwise.
Example:
var callback = new Backendless.Async(
function(result)
{
alert( "category deleted - " + result );
},
function(result)
{
alert( "error - " + result.message );
});
Backendless.Geo.deleteCategory( "mycategory", callback );
5.6 Retrieving Geo Categories
This API retrieves a list of all the application's geo categories.
Methods:
Backendless.Geo.getCategories( async )
Arguments:
async - Asynchronous operation handler. Must contain references to
"success" and "failure" callback functions. The "success" function
receives a callback when the method successfully retrieves the
geo categories in the application. The argument of the "success"
function callback is an array of category objects (see the return
value section). If an error occurs, the faultCallback function is
invoked. See Sync and Async Calls for additional details.
Return Value:
An array of JavaScript objects. Each object has the following structure:
{
"objectId": "<categoryId>",
"size": <categorySize>,
"name": "<categoryName>"
}
where:
<categoryId> - ID assigned by Backendless to the category.
<categorySize> - Number of geo points contained in the geo category.
<categoryName> - Name of the category.
If an error occurs, it is delivered to the faultCallback function referenced in the Async object.
Example:
var callback = new Backendless.Async(
function(result)
{
Backendless API for JavaScript
2014 Backendless Corp.
96
alert( "received " + result.length + " categories" );
},
function(result)
{
alert( "error - " + result.message );
});
Backendless.Geo.getCategories( callback );
5.7 Adding a Geo Point
This API adds a geo point to the backend geo location storage. Once a geo point is added, it becomes
searchable through all search mechanisms supported by Backendless. At the present moment there are
two ways to add geo points: (1) using this API or (2) using the Backendless console's import function.
Methods:
Backendless.Geo.addPoint( geoPoint, async )
Arguments:
geoPoint - a JavaScript object describing the geo point to add. Must have the following
structure:
{
latitude: <latitude>,
longitude: <longitude>,
categories: <categoriesArray>,
metadata: <metadataObj>
}
where:
<latitude> - Latitude of the point to add. Must be a numeric
value.
<longitude> - Longitude of the point to add. Must be a numeric
value.
<categoriesArray> - Optional parameter. Array of categories the point is
added to. If a category does not exist at the time
when a point is added, Backendless creates the
category and adds the point to it. If the property is
not present in the object, the point is added to the
"Default" category. Each category name must be
a string.
<metadataObj> - Optional parameter. Metadata associated with the
geo point. Must be a JavaScript object. Property
names of the object become the key names in the
metadata properties become values of the
corresponding keys.
async - Asynchronous operation handler. Must contain references to "success" and
"failure" callback functions. The "success" function receives a callback when the
method successfully retrieves the geo categories in the application. The argument
of the "success" function callback is an array of category objects (see the return
value section). If an error occurs, the faultCallback function is invoked. See Sync
and Async Calls for additional details.
Geo Service
2014 Backendless Corp.
97
Return Value:
A JavaScript object representing the new geo point. The object has the following structure:
{
geopoint : {
objectId: <objectId>, // ID assigned to the geo point by
Backendless
latitude: <latitude>,
longitude: <longitude>,
categories: <categoriesArray>,
metadata: <metadataObj>
}
}
If an error occurs, it is delivered to the faultCallback function referenced in the Async object.
Example:
var callback = new Backendless.Async(
function( result )
{
alert( "geo point saved " + result.geopoint.objectId );
},
function(result)
{
alert( "error - " + result.message );
});
var point = {
latitude: 20,
longitude: 30,
categories: ["restaurants", "cool_places"],
metadata: {"owner":"XXXX-XXXX-XXXX-XXXX"}
}
Backendless.Geo.addPoint( point, callback );
5.8 Updating a Geo Point
Geo update API relies on the same methods used for Adding a Geo Point. The primary difference is in
order to update a geo point it must have the objectId property assigned by Backendless. The
semantics of the properties in an update request is as follows:
objectId is a required property.
All other properties (latitude, longitude, categories, metadata) are optional, but at least
one must contain a value.
If latitude or longitude contain values, the new values replace the existing ones.
If categories contains a value, the geo point is moved to the specified categories (with
coordinates and metadata).
If categories is null, the geo point stays in the current category.
If metadata is null, the geo point keeps the current metadata.
If metadata contains any key/value pairs, the new metadata replaces the existing one.
If metadata is an empty object/dictionary, the existing metadata is removed.
Backendless API for JavaScript
2014 Backendless Corp.
98
5.9 Importing Geo Data
Backendless console supports bulk import of geo points with metadata. The import procedure
automatically places the geo points into the specified categories. The raw data must be in a comma
separated values (CSV) format. A single line in the file defines one geo point as shown below:
latitude,longitude,"category1,category2","key1=value1|key2=value2"
where:
latitude - The latitude coordinate of a geo point
longitude - The longitude coordinate of a geo point
category1,category2 - Comma separated list of categories. The value must be
enclosed in double quotes.
key1=value1|key2=value2 - Geo point metadata. Multiple key/value pairs must be
separated with the pipe "|" character. The value must be
enclosed in double quotes.
Consider the following example:
40.4165,-3.70256,"restaurants,popular","city=MADRID|cuisine=french|
price=high"
41.38879,2.15899,"restaurants,popular","city=BARCELONA|
cuisine=asian|price=low"
To import geo points:
1. Open Backendless console.
2. Select the application/backend.
3. Click Manage, then Import.
4. Click the "add file" button next to "Geo Service" and select the file to import.
5. Click the "Import" button to initiate the import process.
The import process runs asynchronously. When the process is complete, Backendless sends an email
to the application developer. The email text includes the log entries informing about any errors which
could have occurred during the import. Upon successful completion of the import, the Geolocation
section of the console displays the categories, geo points and their metadata:
Geo Service
2014 Backendless Corp.
99
5.10 Search in Category
This API supports two types of geo searches:
Search in one or more geo categories.
Search in one or more categories based on metadata properties.
Methods:
Backendless.Geo.find( query, async )
Arguments:
query - Query object to run the search with. Must have the following structure:
{
metadata: <metadataObj>,
categories: <categoriesArray>,
includeMetadata: <metaInResponse>,
pageSize: <pageSize>,
offset: <offset>
}
where:
<metadata> - Metadata which must match in order for a point to
be selected for the search result. Must be a
JavaScript object. Backendless searches for geo
points with metadata which matches the specified
object entirely. See partial match search for the
Backendless API for JavaScript
2014 Backendless Corp.
100
search API that does not require complete matches.
<categories> - List of categories separated by comma where to
run the search. If the parameter is not present in the
request, the search is ran in the "Default"
category.
<metaInResponse> - A boolean value indicating whether geo point
metadata should be included in the response.
<pageSize> - Number of geo points to be returned in the
response.
<offset> - Sequential (zero-based) index from where to run
the search. For example, suppose the first search
query returned 50 geo points (pageSize is set to
50). A subsequent search should set the offset
value to 50 in order to get the next page of search
results.
async - Asynchronous operation handler. Must contain references to "success" and
"failure" callback functions. The "success" function receives a callback when
the method successfully completes the search operation (regardless whether
any geo points were found or not). If an error occurs, the faultCallback function
is invoked. See Sync and Async Calls for additional details.
Return Value:
Geo points returned from the search query are contained inside of a collection object. Since the
search query may produce a large number of geo points, not all of them are returned at once.
Instead, all found geo points are divided into 'pages'. The size of each page is determined by the
pageSize parameter in the query object. The first response returns the first page. The collection
class includes methods for loading additional pages. The collection also includes the total number of
all geo points found by the search operation (the totalObjects value).
All geo points in the entire search result are indexed. The index of the first geo point is 0. The
offset parameter in the query object and in the getPage method in the collection specifies the
index from which to load the next page of geo points. For example, suppose the entire search result
is 200 points (the totalObjects value returned in the collection is 200). If the initial pageSize is 20,
then only 20 geo points are returned in the first response. To get the second page of geo points,
they should be loaded from offset 20, third from 40 and so on. The formula for calculating the offset
is:
[value of offset in the current response] + [size of current page ].
The collection object in the response has the following structure and behavior:
{
data: <geoPointCollection>,
offset: <offsetValue>,
totalObjects: <totalObjectsValue>,
getPage : function( offset, pageSize, async );
nextPage: function( async );
}
where:
<geoPointCollection> - Array of geo points objects matching the search
query parameters. Each object has the following
structure:
{
categories: array of category names
Geo Service
2014 Backendless Corp.
101
latitude: latitude of the geo point
longitude: longitude of the geo
point
objectId: ID assigned by
Backendless to the geo point
}
<offsetValue> - Index of the first geo point in the returned collection.
<totalObjectsValue> - Total number of geo points which match the search
query. This number may be different than the number
of geo points in the data array. Points not returned in
the query can be retrieved with a subsequent request,
by setting the offset parameter to:
[value of offset in the current response] + [size of
data array].
getPage - Function responsible for loading a "page" of search
results from the specified offset.
nextPage - Function loading the next page. Should be used only
if data.length is less than totalObjectsValue.
If an error occurs, it is delivered to the faultCallback function referenced in the Async object.
Running Search Queries
The geo query object includes multiple parameters, none of them are required. As a result, depending on
which parameters contain values, the semantics of the search would change. Any search must be
performed within at least one category. If no category names are provided, the search is performed in the
Default category.
Search in categories
To search in one or more categories without any constraints on metadata or proximity to a center point,
simply set the names of the categories in the query object. The request returns all geo points divided
into pages of data, one page at a time.
var callback = new Backendless.Async(
function(result)
{
alert( "found geo points - " + result.data.length );
},
function(result)
{
alert( "error - " + result.message );
});
var geoQuery =
{
categories: ["Restaurants"]
}
Backendless.Geo.find( geoQuery, callback );
Search in categories with metadata
Metadata-based search finds all geo points which match all specified metadata properties in the given
Backendless API for JavaScript
2014 Backendless Corp.
102
categories. The example below searches for the geo points in the Restaurants category with metadata
containing "Cuisine = French" and "Atmosphere = Romantic".
var callback = new Backendless.Async(
function(result)
{
alert( "found geo points - " + result.data.length );
},
function(result)
{
alert( "error - " + result.message );
});
var geoQuery =
{
metadata: {Cuisine:"French", Atmosphere:"Romantic"},
categories: ["Restaurants"]
}
Backendless.Geo.find( geoQuery, callback );
Requesting meta in response
Geo points returned in the search results do not include their metadata properties by default. The search
query object includes a property which can be used to request the metadata to be included. This
property can be used with any search options described above. For example, the following code runs a
search in a category and requests the metadata to be included:
var callback = new Backendless.Async(
function(result)
{
alert( "found geo points - " + result.data.length );
},
function(result)
{
alert( "error - " + result.message );
});
var geoQuery =
{
includeMetadata:true,
categories: ["Restaurants"]
}
Backendless.Geo.find( geoQuery, callback );
5.11 Search in Radius
This API supports multiple types of geo searches:
Search for geo points located within specified distance (radius) from a given point.
Search in radius based on metadata.
Methods:
Backendless.Geo.find( query, async )
Arguments:
query - Query object to run the search with. Must have the following structure:
Geo Service
2014 Backendless Corp.
103
{
radius: <radius>,
latitude: <latitude>,
longitude: <longitude>,
units: <units>,
metadata: <metadataObj>,
categories: <categoriesArray>,
includeMetadata: <metaInResponse>,
pageSize: <pageSize>,
offset: <offset>
}
where:
<radius> - Distance from the center point within which to run
the search.
<latitude> - Latitude of the point in the center of the search.
<longitude> - Longitude of the point in the center of the search.
<units> - Unit of measure applied to the radius value.
Supported unit values are: METERS, KILOMETERS,
MILES, YARDS, FEET
<metadata> - Metadata which must match in order for a point to
be selected for the search result. Must be a
JavaScript object. Backendless searches for geo
points with metadata which matches the specified
object entirely. See partial match search for the
search API that does not require complete matches.
<categories> - List of categories separated by comma where to
run the search. If the parameter is not present in the
request, the search is ran in the "Default"
category.
<metaInResponse> - A boolean value indicating whether geo point
metadata should be included in the response.
<pageSize> - Number of geo points to be returned in the
response.
<offset> - Sequential (zero-based) index from where to run
the search. For example, suppose the first search
query returned 50 geo points (pageSize is set to
50). A subsequent search should set the offset
value to 50 in order to get the next page of search
results.
async - Asynchronous operation handler. Must contain references to "success" and
"failure" callback functions. The "success" function receives a callback when
the method successfully completes the search operation (regardless whether
any geo points were found or not). If an error occurs, the faultCallback function
is invoked. See Sync and Async Calls for additional details.
Return Value:
Geo points returned from the search query are contained inside of a collection object. Since the
search query may produce a large number of geo points, not all of them are returned at once.
Instead, all found geo points are divided into 'pages'. The size of each page is determined by the
pageSize parameter in the query object. The first response returns the first page. The collection
class includes methods for loading additional pages. The collection also includes the total number of
all geo points found by the search operation (the totalObjects value).
Backendless API for JavaScript
2014 Backendless Corp.
104
All geo points in the entire search result are indexed. The index of the first geo point is 0. The
offset parameter in the query object and in the getPage method in the collection specifies the
index from which to load the next page of geo points. For example, suppose the entire search result
is 200 points (the totalObjects value returned in the collection is 200). If the initial pageSize is 20,
then only 20 geo points are returned in the first response. To get the second page of geo points,
they should be loaded from offset 20, third from 40 and so on. The formula for calculating the offset
is:
[value of offset in the current response] + [size of current page ].
The collection object in the response has the following structure and behavior:
{
data: <geoPointCollection>,
offset: <offsetValue>,
totalObjects: <totalObjectsValue>,
getPage : function( offset, pageSize, async );
nextPage: function( async );
}
where:
<geoPointCollection> - Array of geo points objects matching the search
query parameters. Each object has the following
structure:
{
categories: array of category names
distance: distance between the
central point and this geo point in
units
latitude: latitude of the geo point
longitude: longitude of the geo
point
objectId: ID assigned by
Backendless to the geo point
}
<offsetValue> - Index of the first geo point in the returned collection.
<totalObjectsValue> - Total number of geo points which match the search
query. This number may be different than the number
of geo points in the data array. Points not returned in
the query can be retrieved with a subsequent request,
by setting the offset parameter to:
[value of offset in the current response] + [size of
data array].
getPage - Function responsible for loading a "page" of search
results from the specified offset.
nextPage - Function loading the next page. Should be used only
if data.length is less than totalObjectsValue.
If an error occurs, it is delivered to the faultCallback function referenced in the Async object.
Running Search Queries
Geo Service
2014 Backendless Corp.
105
The geo query object includes multiple parameters, none of them are required. As a result, depending on
which parameters contain values, the semantics of the search would change. Any search must be
performed within at least one category. If no category names are provided, the search is performed in the
Default category.
Search in categories with radius
Radius-based search establishes a circular area by setting the coordinates of a central point and a
distance (radius). Backendless searches for geo points in the specified distance from the coordinates in
the center and includes them into the search result. The value of the distance is interpreted based in the
units parameter, which can be METERS, KILOMETERS, MILES, YARDS, FEET:
var callback = new Backendless.Async(
function(result)
{
alert( "found geo points - " + result.data.length );
},
function(result)
{
alert( "error - " + result.message );
});
var geoQuery =
{
latitude: 41.38,
longitude: 2.15,
radius: 100000,
units: "METERS",
categories: ["Restaurants"]
}
Backendless.Geo.find( geoQuery, callback );
Search in categories with radius and metadata
This is the same as above, with the difference that the search result includes only geo points with the
matching metadata:
var callback = new Backendless.Async(
function(result)
{
alert( "found geo points - " + result.data.length );
},
function(result)
{
alert( "error - " + result.message );
});
var geoQuery =
{
latitude: 41.38,
longitude: 2.15,
radius: 100000,
units: "METERS",
metadata: {Cuisine:"French", Atmosphere:"Romantic"},
categories: ["Restaurants"]
}
Backendless.Geo.find( geoQuery, callback );
Backendless API for JavaScript
2014 Backendless Corp.
106
Requesting meta in response
Geo points returned in the search results do not include their metadata properties by default. The search
query object includes a property which can be used to request the metadata to be included. This
property can be used with any search options described above. The syntax for requesting metadata in
response is described in the Search in Category section.
5.12 Search in Rectangular Area
This API runs a search within a rectangular area of the map. The area is defined with the coordinates of
the North West and South East corners of the map rectangle.
Methods:
Backendless.Geo.find( query, async )
Arguments:
query - Query object to run the search with. Must have the following structure:
{
searchRectangle: <search-rect-coord>,
metadata: <metadataObj>,
categories: <categoriesArray>,
includeMetadata: <metaInResponse>,
pageSize: <pageSize>,
offset: <offset>
}
where:
<search-rect-coord> - An array of 4 numbers which are the
coordinates defining the search area. The
numbers must be in the following order:
[
North West latitude,
North West longitude,
South East latitude,
South East longitude
]
<metadata> - Metadata which must match in order for a
point to be selected for the search result.
Must be a JavaScript object. Backendless
searches for geo points with metadata which
matches the specified object entirely. See
partial match search for the search API that
does not require complete matches.
<categories> - List of categories separated by comma
where to run the search. If the parameter is
not present in the request, the search is ran in
the "Default" category.
<metaInResponse> - A boolean value indicating whether geo point
metadata should be included in the response.
<pageSize> - Number of geo points to be returned in the
response.
<offset> - Sequential (zero-based) index from where to
Geo Service
2014 Backendless Corp.
107
run the search. For example, suppose the first
search query returned 50 geo points (
pageSize is set to 50). A subsequent search
should set the offset value to 50 in order to
get the next page of search results.
async - Asynchronous operation handler. Must contain references to "success" and
"failure" callback functions. The "success" function receives a callback when
the method successfully completes the search operation (regardless whether
any geo points were found or not). If an error occurs, the faultCallback function
is invoked. See Sync and Async Calls for additional details.
Return Value:
Geo points returned from the search query are contained inside of a collection object. Since the
search query may produce a large number of geo points, not all of them are returned at once.
Instead, all found geo points are divided into 'pages'. The size of each page is determined by the
pageSize parameter in the query object. The first response returns the first page. The collection
class includes methods for loading additional pages. The collection also includes the total number of
all geo points found by the search operation (the totalObjects value).
All geo points in the entire search result are indexed. The index of the first geo point is 0. The
offset parameter in the query object and in the getPage method in the collection specifies the
index from which to load the next page of geo points. For example, suppose the entire search result
is 200 points (the totalObjects value returned in the collection is 200). If the initial pageSize is 20,
then only 20 geo points are returned in the first response. To get the second page of geo points,
they should be loaded from offset 20, third from 40 and so on. The formula for calculating the offset
is:
[value of offset in the current response] + [size of current page ].
The collection object in the response has the following structure and behavior:
{
data: <geoPointCollection>,
offset: <offsetValue>,
totalObjects: <totalObjectsValue>,
getPage : function( offset, pageSize, async );
nextPage: function( async );
}
where:
<geoPointCollection> - Array of geo points objects matching the search
query parameters. Each object has the following
structure:
{
categories: array of category names
latitude: latitude of the geo point
longitude: longitude of the geo
point
objectId: ID assigned by
Backendless to the geo point
}
<offsetValue> - Index of the first geo point in the returned collection.
<totalObjectsValue> - Total number of geo points which match the search
query. This number may be different than the number
of geo points in the data array. Points not returned in
Backendless API for JavaScript
2014 Backendless Corp.
108
the query can be retrieved with a subsequent request,
by setting the offset parameter to:
[value of offset in the current response] + [size of
data array].
getPage - Function responsible for loading a "page" of search
results from the specified offset.
nextPage - Function loading the next page. Should be used only
if data.length is less than totalObjectsValue.
If an error occurs, it is delivered to the faultCallback function referenced in the Async object.
Running Search Queries
The geo query object includes multiple parameters, however, only the coordinates defining the
rectangular area are required. A search query must be performed within at least one category. If no
category names are provided, the search is performed in the Default category.
Search in a rectangle in categories
Rectangle-based search establishes a geographic area by setting the coordinates of the North West and
South East corners of the area. Backendless searches for geo points in the specified area and includes
them into the search result:
var callback = new Backendless.Async(
function(result)
{
alert( "found geo points - " + result.data.length );
},
function(result)
{
alert( "error - " + result.message );
});
var geoQuery =
{
searchRectangle: [32.78, -96.8, 25.79, -80.22],
categories: ["Restaurants"]
}
Backendless.Geo.find( geoQuery, callback );
Search in categories in a rectangular area and metadata
This is the same as above, with the difference that the search result includes only geo points with the
matching metadata:
var callback = new Backendless.Async(
function(result)
{
alert( "found geo points - " + result.data.length );
},
function(result)
{
alert( "error - " + result.message );
});
var geoQuery =
Geo Service
2014 Backendless Corp.
109
{
searchRectangle: [32.78, -96.8, 25.79, -80.22],
metadata: {Cuisine:"French", Atmosphere:"Romantic"},
categories: ["Restaurants"]
}
Backendless.Geo.find( geoQuery, callback );
Requesting meta in response
Geo points returned in the search results do not include their metadata properties by default. The search
query object includes a property which can be used to request the metadata to be included. This
property can be used with any search options described above. The syntax for requesting metadata in
response is described in the Search in Category section.
5.13 Partial Match Search
TBD
Backendless API for JavaScript 110
2014 Backendless Corp.
Index
- B -
backendless.jar 5, 53, 73, 88
- I -
Identity 7
- L -
Login 13
Logout 19
- P -
Password
property 7
recovery 21
- U -
User Properties
defining with API 7
defining with console 7
retrieve user entity description 9
update user registration 17
User Registration
API call 10
disable registration 10
email confirmation 10
registration with external system 10
Endnotes 2... (after index)
111
2014 Backendless Corp.
Back Cover

S-ar putea să vă placă și