Cloud API

Red Hat Mobile Application Platform Hosted 4

For Red Hat Mobile Application Platform Hosted 4

Red Hat Customer Content Services

Abstract

This document is a reference of the RHMAP Cloud API.

Chapter 1. $fh.cache

$fh.cache(options, callback);

Store, read or delete a value in the cache layer of your Cloud App.

By default, the cache store has a memory limit of 1GB. Once the limit is reached, the store starts removing data using an LRU (Least Recently Used) algorithm.

If the option "expire" is not specified when storing a value in the cache, that value remains in the cache until the memory limit is reached. Then, the LRU algorithm determines which value is removed.

1.1. Managing the cache options

The memory limit for the cache can be managed in the Studio, which also allows you to flush the cache store. These two options are available in Resources > [environment] > Cache

Note

The Max Cache Size limit setting affects all Cloud Apps for an environment.

Manage cache

1.2. Examples

Save a value to the cache

var options = {
  "act": "save",
  "key": "foo", // The key associated with the object
  "value": "bar", // The value to be cached, must be serializable
  "expire": 60 // Expiry time in seconds. Optional
};
$fh.cache(options, function (err, res) {
  if (err) return console.error(err.toString());

  // res is the original cached object
  console.log(res.toString());
});

Load a value from the cache

var options = {
  "act": "load",
  "key": "foo" // key to look for in cache
};
$fh.cache(options, function (err, res) {
  if (err) return console.error(err.toString());

  // res is the original cached object
  console.log(res.toString());
});

Remove a value from the cache

var options = {
  "act": "remove",
  "key": "foo" // key to look for in cache
};
$fh.cache(options, function (err, res) {
  if (err) return console.error(err.toString());

  // res is the removed cached object
  console.log(res.toString());
});

Chapter 2. $fh.db

$fh.db(options, callback);

Access to hosted data storage. It supports CRUDL (create, read, update, delete, list) and index operations. It also supports deleteall, which deletes all the records in the specified entity.

2.1. Example

Create a single entry (row)

var options = {
  "act": "create",
  "type": "myFirstEntity", // Entity/Collection name
  "fields": { // The structure of the entry/row data. A data is analogous to "Row" in MySql or "Documents" in MongoDB
    "firstName": "Joe",
    "lastName": "Bloggs",
    "address1": "22 Blogger Lane",
    "address2": "Bloggsville",
    "country": "Bloggland",
    "phone": "555-123456"
  }
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
    /*
       The output will be something similar to this
       {
        "fields": {
          "address1": "22 Blogger Lane",
          "address2": "Bloggsville",
          "country": "Bloggland",
          "fistName": "Joe",
          "lastName": "Bloggs",
          "phone": "555-123456"
        },
        "guid": "4e563ea44fe8e7fc19000002", // unique id for this data entry
        "type": "myFirstEntity"
      }
    */
  }
});

Create multiple records in one call

var options = {
  "act": "create",
  "type": "myCollectionType", // Entity/Collection name
  "fields": [{ // Notice 'fields' is an array of data entries
    "id": 1,
    "name": "Joe"
  }, {
    "id": 2,
    "name": "John"
  }]
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
    /*
       The output will be something similar to this
       {
          "status":"ok",
          "count": 2
       }
    */
  }
});

Read a single entry

var options = {
  "act": "read",
  "type": "myFirstEntity", // Entity/Collection name
  "guid": "4e563ea44fe8e7fc19000002" // Row/Entry ID
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
    /* Sample output
      {
        "fields": {
          "address1": "22 Blogger Lane",
          "address2": "Bloggsville",
          "country": "Bloggland",
          "fistName": "Joe",
          "lastName": "Bloggs",
          "phone": "555-123456"
        },
        "guid": "4e563ea44fe8e7fc19000002",
        "type": "myFirstEntity"
      }
    */
  }
});

Update an entire entry

// The update call updates the entire entity.
// It will replace all the existing fields with the new fields passed in.
var options = {
  "act": "update",
  "type": "myFirstEntity", // Entity/Collection name
  "guid": "4e563ea44fe8e7fc19000002", // Row/Entry ID
  "fields": {
    "fistName": "Jane"
  }
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
    /* Output:
      {
        "fields": {
          "fistName": "Jane"   //only one field now
        },
        "guid": "4e563ea44fe8e7fc19000002",
        "type": "myFirstEntity"
      }
    */
  }
});

Update a single field

var options = {
  "act": "read",
  "type": "myFirstEntity", // Entity/Collection name
  "guid": "4e563ea44fe8e7fc19000002" // Row/Entry ID
};
$fh.db(options, function (err, entity) {
  var entFields = entity.fields;
  entFields.firstName = 'Jane';

  options = {
    "act": "update",
    "type": "myFirstEntity",
    "guid": "4e563ea44fe8e7fc19000002",
    "fields": entFields
  };
  $fh.db(options, function (err, data) {
    if (err) {
      console.error("Error " + err);
    } else {
      console.log(JSON.stringify(data));
      /*output
        {
          "fields": {
            "address1": "22 Blogger Lane",
            "address2": "Bloggsville",
            "country": "Bloggland",
            "firstName": "Jane",
            "lastName": "Bloggs",
            "phone": "555-123456"
          },
          "guid": "4e563ea44fe8e7fc19000002",
          "type": "myFirstEntity"
        }
      */
    }
  });
});

Delete an entry (row)

var options = {
  "act": "delete",
  "type": "myFirstEntity", // Entity/Collection name
  "guid": "4e563ea44fe8e7fc19000002" // Row/Entry ID to delete
};
$fh.db(, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
    /* output
      {
        "fields": {
          "address1": "22 Blogger Lane",
          "address2": "Bloggsville",
          "country": "Bloggland",
          "fistName": "Jane",
          "lastName": "Bloggs",
          "phone": "555-123456"
        },
        "guid": "4e563ea44fe8e7fc19000002",
        "type": "myFirstEntity"
      }
    */
  }
});

Delete all entity (collection) entries

var options = {
  "act": "deleteall",
  "type": "myFirstEntity" // Entity/Collection name
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
    /* output
      {
        status: "ok",
        count: 5
      }
    */
  }
});

List

var options = {
  "act": "list",
  "type": "myFirstEntity", // Entity/Collection name
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
  /* output
    {
      "count": 1,
      "list": [{
        "fields": {
          "address1": "22 Blogger Lane",
          "address2": "Bloggsville",
          "country": "Bloggland",
          "fistName": "Joe",
          "lastName": "Bloggs",
          "phone": "555-123456"
        },
        "guid": "4e563ea44fe8e7fc19000002",
        "type": "myFirstEntity"
      }]
    }
    */
  }
});

List with sorting

var sort_ascending = {
  "act": "list",
  "type": "myFirstEntity", // Entity/Collection name
  "sort": {
    "username": 1 // Sort by the 'username' field ascending a-z
  }
};

var sort_descending = {
  "act": "list",
  "type": "myFirstEntity", // Entity/Collection name
  "sort": {
    "username": -1 // Sort by the 'username' field descending z-a
  }
};

List with pagination

var options = {
  "act": "list",
  "type": "myFirstEntity", // Entity/Collection name
  "skip": 20,   1
  "limit": 10   2
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
    /* output
    {
      "count": 10,
      "list": [{
        "fields": {
          "address1": "22 Blogger Lane",
          "address2": "Bloggsville",
          "country": "Bloggland",
          "fistName": "Joe",
          "lastName": "Bloggs",
          "phone": "555-123456"
        },
        "guid": "4e563ea44fe8e7fc19000002",
        "type": "myFirstEntity"
      }, ...
      ]
    }
    */
  }
});

1
returns the third page of results
2
the size of the returned page is 10

List with Geo search

var options = {
  act: "list",
  type: "collectionName", // Entity/Collection name
  "geo": {
    "employeeLocation": { //emplyeeLocation has been indexed as "2D"
      center: [-83.028965, 42.542144],
      radius: 5 //km
    }
  }
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
  /* output
    {
      "count": 1,
      "list": [{
        "fields": {
          "address1": "22 Blogger Lane",
          "address2": "Bloggsville",
          "country": "Bloggland",
          "fistName": "Joe",
          "lastName": "Bloggs",
          "phone": "555-123456"
        },
        "guid": "4e563ea44fe8e7fc19000002",
        "type": "myFirstEntity"
      }]
    }
    */
  }
});

List with multiple restrictions

/* Possible query restriction types:
  "eq" - is equal to
  "ne" - not equal to
  "lt" - less than
  "le" - less than or equal
  "gt" - greater than
  "ge" - greater than or equal
  "like" Match some part of the field. Based on [Mongo regex matching logic](http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions)
  "in" - The same as $in operator in MongoDB, to select documents where the field (specified by the _key_) equals any value in an array (specified by the _value_)
*/
var options = {
  "act": "list",
  "type": "myFirstEntity", // Entity/Collection name
  "eq": {
    "lastName": "Bloggs"
  },
  "ne": {
    "firstName": "Jane"
  },
  "in": {
    "country": ["Bloggland", "Janeland"]
  }
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
  /* output
    {
      "count": 1,
      "list": [{
        "fields": {
          "address1": "22 Blogger Lane",
          "address2": "Bloggsville",
          "country": "Bloggland",
          "fistName": "Joe",
          "lastName": "Bloggs",
          "phone": "555-123456"
        },
        "guid": "4e563ea44fe8e7fc19000002",
        "type": "myFirstEntity"
      }]
    }
    */
  }
});

List with restricted fields returned

var options = {
  "act": "list",
  "type": "myFirstEntity",
  "eq": {
    "lastName": "Bloggs",
    "country": "Bloggland"
  },
  "ne": {
    "firstName": "Jane"
  },
  "fields": ["address1", "address2"]
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
  /* output
    {
      "count": 1,
      "list": [{
        "fields": {
          "address1": "22 Blogger Lane",
          "address2": "Bloggsville"
        },
        "guid": "4e563ea44fe8e7fc19000002",
        "type": "myFirstEntity"
      }]
    }
    */
  }
});

Adding an index

var options = {
  "act": "index",
  "type": "employee",
  "index": {
    "employeeName": "ASC" // Index type: ASC - ascending, DESC - descending, 2D - geo indexation
    "location": "2D"
    // For 2D indexing, the field must satisfy the following:
    //  It is a [Longitude, Latitude] array
    //  Longitude should be between [-180, 180]
    //  Latitude should be between [-90, 90]
    //  Latitude or longitude should **NOT** be null
  }
};
$fh.db(options, function (err, data) {
  if (err) {
    console.error("Error " + err);
  } else {
    console.log(JSON.stringify(data));
    /* output
      {
        "status":"ok",
        "indexName":"employeeName_1_location_2d"
      }
    */
  }
});

Chapter 3. $fh.forms

3.1. $fh.forms.getForms

$fh.forms.getForms(options, callback);

Return an array of JSON objects with form summary information.

Note

These form summary JSON objects do not contain the full form definition. Use the $fh.forms.getForm function to get a full form definition.

3.1.1. Example

//Get a list of forms associated with the project.
var options = {

};

$fh.forms.getForms(options,

/*
* Function executed with forms.
*/
function (err, response) {
  if (err) return handleError(err);

  //An Array Of Forms Associated With The Project
  var formsArray = response.forms;

   /*
     exampleForm: {
      _id: <<Form Id>>,
      name: <<Form Name>>,
      description: <<Form Description>>
      lastUpdatedTimestamp: <<Timestamp of when the form was last updated>>
    }
  */
  var exampleForm = formsArray[0];

  return callback(undefined, formsArray);
});

3.2. $fh.forms.getForm

  $fh.forms.getForm(options, callback)

3.2.1. Details

Retrieve specific form model based on form ID. Form IDs can be obtained using the $fh.forms.getForms function.

3.2.2. Example

$fh.forms.getForm({
  "_id": formId
}, function (err, form) {
  if (err) return handleError(err);


  /*
    A JSON object describing a full form object.
  */
  return callback(undefined, form);
});

3.3. $fh.forms.getPopulatedFormList

  $fh.forms.getPopulatedFormList(options, callback)

3.3.1. Details

Retrieve form models based on a list of form IDs.

3.3.2. Example

$fh.forms.getPopulatedFormList({
  "formids": [formId1, formId2 ... ]
}, function (err, arrayOfForms) {
  if (err) return handleError(err);


  /*
    A JSON object describing a full form object.
  */
  return callback(undefined, arrayOfForms);
});

3.4. $fh.forms.getSubmissions

  $fh.forms.getSubmissions(options, callback)

3.4.1. Details

List all Submissions based on filtering criteria

3.4.2. submissionsObject

{
  submissions: [<SubmissionJSON>, <SubmissionJSON>]
}

3.4.3. Example

$fh.forms.getSubmissions({
  "formId": [formId1, formId2 ... ],
  "subid": [subId1, subId2 ...]
}, function (err, submissionsObject) {
  if (err) return handleError(err);


  /*
    An Object Containing An Array of JSON objects describing a full Submission object.
  */
  return callback(undefined, submissionsObject);
});

3.5. $fh.forms.getSubmission

  $fh.forms.getSubmission(options, callback)

3.5.1. Details

Get A Single Form Submission

3.5.2. Example

$fh.forms.getSubmissions({
  "submissionId": subId1
}, function (err, submission) {
  if (err) return handleError(err);


  /*
    A JSON object describing a full Submission object.
  */
  return callback(undefined, submission);
});

3.6. $fh.forms.getSubmissionFile

  $fh.forms.getSubmissionFile(options, callback)

3.6.1. Details

Stream a single file contained in a submission. Files are accessed using the fileGroupId field in a submission file field.

3.6.2. fileStreamObject

{
  stream: <Readable File Stream>
}

3.6.3. Example

$fh.forms.getSubmissionFile({
  "_id": fileGroupId
}, function (err, fileStreamObject) {
  if (err) return handleError(err);


  /**
  * Pipe the file stream to a writable stream (for example, a FileWriter)
  */
  fileStreamObject.stream.pipe(writable_stream);
  fileStreamObject.stream.resume();
});

3.7. Form JSON Definition

A form JSON object contains all of the information needed to process a form.

{
   "_id":"<<24 Character Form ID>>",
   "description":"This is an example form definition",
   "name":"Example Form",
   "updatedBy":"<<User ID of the person that last updated the form>>",
   "lastUpdatedTimestamp":1410876316105, //Time the form was last updated.
   "subscribers":[
   //Email addresses to be notified when a submission has been made against this form.
    "notifiedUser1@example.com",
    "notifiedUser2@example.com"
   ],
   "pageRules":[
      <<Page Rule JSON Object>>
   ],
   "fieldRules":[
      <<Field Rule JSON Object>>
   ],
   "pages":[
      <<Page JSON Object>>,
   ],
   //Convenient reference for the index of a page with <<Page Id>> in the "pages" array.
   "pageRef":{
      "<<Page Id>>":0,
      "<<Page Id>>":1
   },
   //Convenient reference for the index of a field. Both the page index and field index are given.
   "fieldRef":{
      "<<Field Id>>":{
         "page":0,
         "field":0
      },
      "<<Field Id>>":{
         "page":0,
         "field":1
      }
   }
}

3.7.1. Page

{
   "_id":"<<Page ID>>",
   "name":"Page 1",
   "fields":[
      <<Field JSON Object>>
   ]
}

3.7.2. Field

{
  "_id":"<<Field ID>>",
   "required":true,
   "type":"text",//Field Type
   "name":"A Sample Text Field",
   "repeating":false/true //Boolean that describes if a field is repeating or not.
   "fieldOptions":{
      "validation":{ // Optional validation parameters for the form.
         "validateImmediately":true //Flag for whether field inputs should be immediately validated (for example, On-Blur on a Client App.)
      },
      "definition": {// Optional definition options.
          "minRepeat": 2, //Minimum number of entries for this field.
          "maxRepeat": 5 //Maximum number of entries for this field.
      }
   }
}

3.7.3. Page Rule

This JSON object describes a Page Rule created in the Studio.

{
   "type":"skip",//A "skip" or "show" page rule
   "_id":"<<ID of the Page Rule>>",
   "targetPage":[
      "<<ID of the Page targeted by the Page Rule>>"
   ],
   "ruleConditionalStatements":[
      {
         "sourceField":"<<ID of the Field this condition is sourcing data from>>",
         "restriction":"is",// Comparator operator for the conditional statement.
         "sourceValue":"skippage" //Value To Compare.
      }
   ],
   //Combinator for "ruleConditionalStatements".  Can be "and" or "or".
   "ruleConditionalOperator":"and",
}

3.7.4. Field Rule

This JSON object describes a Field Rule created in the Studio.

{
   "type":"hide/show", //A "hide" or "show" field rule
   "_id":"<<ID of the Field Rule>>",
   "targetField":[
      "<<ID of the Field targeted by the Field Rule>>"
   ],
   "ruleConditionalStatements":[
      {
         "sourceField":"<<ID of the Field this condition is sourcing data from>",
         "restriction":"is",// Comparator operator for the conditional statement.
         "sourceValue":"hideMe" //Value To Compare.
      }
   ],
   //Combinator for "ruleConditionalStatements".  Can be "and" or "or".
   "ruleConditionalOperator":"and"
}

3.8. $fh.forms.getTheme

  $fh.forms.getTheme(options, callback)

3.8.1. Details

Loads a JSON object representing the Theme that is assigned to the Project.

3.8.2. Example

//Currently no parameters for loading a theme.
var options = {

};

$fh.forms.getTheme({}, function (err, theme) {
  if (err) return handleError(err);

  return callback(undefined, theme);
});

3.8.3. $fh.forms.getAppClientConfig

  $fh.forms.getAppClientConfig(options, callback)

3.8.4. Details

Returns a JSON object containing Client Config settings associated with the Project. These are configured in the Studio.

3.8.5. Example

//Currently no options for loading app config.
var options = {

};

$fh.forms.getAppClientConfig(options, function (err, clientConfig) {
  if (err) return handleError(err);


  return callback(undefined, clientConfig);
});

3.8.6. Client Config JSON Object

{
  "sent_items_to_keep_list": [5, 10, 20, 30, 40, 50, 100], //Array representing options available to
  "targetWidth": 480, //Camera Photo Width
  "targetHeight": 640, //Camera Photo Height
  "quality": 75, //Camera Photo Quality
  "debug_mode": false, //Set the Client To Debug Mode
  "logger" : false, //Client Logging
  "max_retries" : 0, //Maximum number of failed uplod attempts before returning an error to the user
  "timeout" : 30,// Number of seconds before a form upload times out.
  "log_line_limit": 300,//Maximum number of log entries before rotating logs
  "log_email": "test@example.com" //The email address that logs are sent to.
}

3.9. $fh.forms.submitFormData

   $fh.forms.submitFormData(options, callback)

3.9.1. Details

Submits a JSON object representing a Form Submission.

3.9.1.1. Example

var options = {
  "submission": <<Submission JSON Object>>,
  "appClientId": <<ID Of The Client Making The Submission.>>
};

$fh.forms.submitFormData(options, function(err,data){
  if(err) return callback(err);

  return callback(null,data);
});

3.9.2. Submission JSON Object

{
  "formId": "<<ID Of Form Submitting Agains>>",
  "deviceId": "<<ID of the device submitting the form>>",
  "deviceIPAddress": "<<IP Address of the device submitting the form>>",
  "formFields": [<<Field Entry JSON Object>>],
  "deviceFormTimestamp": "<<lastUpdatedTimestamp of the Form that the submission was submitted against.>>",
  "comments": [{ //Optional comments related to the submission
    "madeBy": "user",
    "madeOn": "12/11/10",
    "value": "This is a comment"
  }]
}

3.9.3. Field Entry JSON Object

{
  fieldId: <<ID Of The Field "fieldValues" Are Submitted Against>>,
  fieldValues: [<<Field Value Entry>>]
}

3.9.4. Field Value Entries

This presents the data format required for each type of field submission.

  • Text: String
  • TextArea: String
  • Number: Number
  • Radio: String (Must represent one of the Radio Field options defined in the Form)
  • Dropdown: String (Must represent one of the Dropdown options represented in the Form)
  • Webstite: String
  • Email: String (Must be a valid email format)
  • DateStamp - Date Only: String (Format: DD/MM/YYYY)
  • DateStamp - Time Only: String (Format: HH:SS)
  • DateStamp - Date & Time: String (Format: YYYY-MM-DD HH:SS)

Check boxes

{
  selections: ["Check box Option 1", .... , "Check box Option 4"]
}

Location (And Map Field) - Latitude & Longitude

{
  lat: <<Valid Latitude Value>,
  long: <<Valid Longitude Value>>
}

Location - Northings & Eastings

{
  zone: "11U",
  eastings: 594934,
  northings: 5636174
}

File Based Fields - File, Photo, Signature

{
  fileName: <<Name of the file to be uploaded>>,
  fileType: <<Valid mime type of the file>>,
  fileSize: <<Size of the file in Bytes>>,
  fileUpdateTime: <<Timestamp of the time the file was saved to device>>,
  hashName: "filePlaceHolder12345" //A unique identifer for the fole. NOTE: Must begin with "filePlaceHolder"
}
Note

All hashName parameters must begin with filePlaceHolder or the submission will be rejected.

3.10. $fh.forms.getSubmissionStatus

  $fh.forms.getSubmissionStatus(options, callback)

3.10.1. Details

Returns the current status of the submission.

3.10.2. Example

var options = {
  submission: {
    //This is the submission ID returned when the $fh.forms.submitFormData function returns.
    submissionId: "<<Remote Submission ID>>"
  }
};

$fh.forms.getSubmissionStatus(options, function(err, submissionStatus){
   if(err) return handleError(err);

  return callback(undefined, submissionStatus);
});

3.10.3. Submission Status JSON Object

Note

A submission is only marked as complete after the $fh.forms.completeSubmission function has been called. Therefore it is possible that the pendingFiles array can be empty and the status set as pending.

{
  "status": "pending/complete", //Status can either be pending or complete
  "pendingFiles": [
    "<<hashName of file not uploaded yet. (for example, filePlaceHolder1234)>>"
  ]
}

3.11. $fh.forms.submitFormFile

  $fh.forms.submitFormFile(options, callback)

3.11.1. Details

Uploads a file to the submission.

Note

The file must already be added to the Submission JSON Object and submitted using the $fh.forms.submitFormData function.

Note

The file must already exist on the local file system to upload it to the submission.

Warning

If the keepFile parameter is not set to true, the file uploaded to the submission will be deleted from the file system when upload is complete.

3.11.2. Example

var options = {
  "submission": {
    "fileId": "<<The File hashName>>",
    "submissionId": "<<The Submission ID Containing The File Input>>",
    "fieldId": "<<Field Id The File Is Being Submitted Against>>",
    "fileStream": "<</path/to/the/file/stored/locally>>" //path to the file
    "keepFile": true/false //Keep the file storated at "fileStream" when it has been uploaded.
  }
 }

$fh.forms.submitFormFile(options, function(err, submitFileResult){
  if(err) return handleError(err);

  //File upload has completed successfully
  return callback(undefined, submitFileResult);
});

3.11.3. submitFileResult JSON Object

{
  status: 200 //Indicating that the file has uploaded successfully
  savedFileGroupId: <<Server ID of the file held in the submission>>
}

3.12. $fh.forms.completeSubmission

  $fh.forms.completeSubmission(options, callback)

3.12.1. Details

Mark the submission as complete. This will check that all of the files submitted as part of the Submission JSON have been uploaded.

If the submission has completed successfully, the completeResult JSON object will contain

{
  "status": "complete"
}

If submitted files have not been uploaded the completeResult JSON object will contain

{
  "status": "pending",
  "pendingFiles": [
    "<<hashName of file not uploaded yet. (for example, filePlaceHolder1234)>>"
  ]
}

3.12.2. Example

var options = {
  "submission": {
      "submissionId": "<<The ID of the Submission to Complete>>"
    }
}

$fh.forms.completeSubmission(options, function (err, completeResult) {
  if (err) return handleError(err);

  return callback(undefined, completeResult);
});

3.13. $fh.forms.createSubmissionModel

3.13.1. Details

The $fh.forms.createSubmissionModel function is an alternative method of creating and submitting a form.

The Submission Model provides some convenience functions to make the process of creating a submission easier.

3.13.2. Example

var options = {
  "form": <<A Form JSON Object Obtained using $fh.forms.getForm>>
};

$fh.forms.createSubmissionModel(options, function(err, submissionModel){
  if (err) return handleError(err);

  //Now use the Submisison Model Functions To Add data to the Submission
  var fieldInputOptions = {
    "fieldId": "<<The ID of the field To Add Data To>>",
    "fieldCode": "<<The fieldCode of the field To Add Data To>>"
    "index": "<<The index to add the value to>>" //(This is used for repeating fields with mutiple values)
    "value": "<<A valid input value to add to the submission>>"
  };

  //Note: the addFieldInput function is not asynchronous
  var error = submissionModel.addFieldInput(fieldInputOptions);

  if(error){
    return handleError(error);
  }

  /*
  Submitting the data as part of a submission.
  This function will upload all files passed to the submission using the addFieldInput function
  */
  submissionModel.submit(function(err, submissionId){
    if(err) return handleError(err);

    return callback(undefined, submissionId);
  });
});

3.14. $fh.forms.registerListener

Note

The version of fh-mbaas-api in your package.json file must be at least 4.8.0.

3.14.1. Details

The $fh.forms.registerListener function allows you to register an EventEmitter object to listen for submission events that occur.

Note

The $fh.forms.registerListener and $fh.forms.deregisterListener functions only accept EventEmitter objects as parameters.

//NodeJS Events Module. Note, this is required to register event emitter objects to forms.
var events = require('events');
var submissionEventListener = new events.EventEmitter();

$fh.forms.registerListener(submissionEventListener, function(err){
  if (err) return handleError(err);

  //submissionEventListener has now been registered with the $fh.forms Cloud API. Any valid Forms Events will now emit.
});

3.14.2. Event: submissionStarted

This event is emitted whenever a submission has been submitted, validated and saved to the database. This occurs before any files are uploaded as part of the submission.

The object passed to the submissionStarted event contains the following parameters:

{
    "submissionId": "<<24-character submission ID>>",
    "submissionStartedTimestamp": "<<2015-02-04T19:18:58.746Z>>"
}
//NodeJS Events Module. Note, this is required to register event emitter objects to forms.
var events = require('events');
var submissionEventListener = new events.EventEmitter();

submissionEventListener.on('submissionStarted', function(params){
  var submissionId = params.submissionId;
  var submissionStartedTimestamp = params.submissionStartedTimestamp;
  console.log("Submission with ID " + submissionId + " has started at " + submissionStartedTimestamp);
});

$fh.forms.registerListener(submissionEventListener, function(err){
  if (err) return handleError(err);

  //submissionEventListener has now been registered with the $fh.forms Cloud API. Any valid Forms Events will now emit.
});

3.14.3. Event: submissionComplete

This event is emitted whenever a submission has been submitted, has been validated and saved to the database, all files have been saved to the database and the submission has been verified. The submission is now ready for processing using the $fh.forms.getSubmission Cloud API.

//NodeJS Events Module. Note, this is required to register event emitter objects to forms.
var events = require('events');
var submissionEventListener = new events.EventEmitter();

submissionEventListener.on('submissionComplete', function(params){
  var submissionId = params.submissionId;
  var submissionCompletedTimestamp = params.submissionCompletedTimestamp;
  console.log("Submission with ID " + submissionId + " has completed at " + submissionCompletedTimestamp);
});

$fh.forms.registerListener(submissionEventListener, function(err){
  if (err) return handleError(err);

  //submissionEventListener has now been registered with the $fh.forms Cloud API. Any valid Forms Events will now emit.
});

The params object passed to the event contains:

{
    "submissionId": "<<24-character submission ID>>",
    "submissionCompletedTimestamp": "<<2015-02-04T19:18:58.746Z>>",
    "submission": "<<JSON definition of the Completed Submission.>>"
}

3.14.4. Event: submissionError

This event is emitted whenever an error has occurred when making a submission.

//NodeJS Events Module. Note, this is required to register event emitter objects to forms.
var events = require('events');
var submissionEventListener = new events.EventEmitter();

submissionEventListener.on('submissionError', function(error){
  console.log("Error Submitting Form");
  console.log("Error Type: ", error.type);
});

$fh.forms.registerListener(submissionEventListener, function(err){
 if (err) return handleError(err);

 //submissionEventListener has now been registered with the $fh.forms Cloud API. Any valid Forms Events will now emit.
});

3.14.4.1. Submission Error Types

Submission errors fall into different types depending on the reason for the error.

3.14.4.1.1. Validation Error

The submitted data is not valid. The response will be in the following format:

Note

For repeating fields, the error messages will be in the same order as the values entered for the field.

{
  type: 'validationError',
  error: {
       valid: < true / false >,
       < fieldId1 >: {
           valid: < true / false >,
           errorMessages: [
               "Validation Error Message 1",
               "Validation Error Message 2"
           ]
       },
       ....,
       < fieldIdN >: {
           valid: < true / false >,
           errorMessages: [
               "Validation Error Message 1",
               "Validation Error Message 2"
           ]
       }
   }
}
3.14.4.1.2. Other Errors Saving The JSON Definition Of The Submission

There was an unexpected error saving the JSON definition of the submission. This event covers all errors other than validation that can occur when attempting to save the submission (For example, an error occurred when saving the submission to the database).

{
  type: 'jsonError',
  error: < Error message >
}
3.14.4.1.3. File Upload Error

There was an error uploading a file for a submission.

{
  type: 'fileUploadError',
  submissionId: < ID of the submission related to the file upload >,
  fileName: < The name of the file uploaded>,
  error: < Error message >
}

3.15. $fh.forms.deregisterListener

Note

The version of fh-mbaas-api in your package.json file must be at least 4.8.0.

3.15.1. Details

Removes a listener from the $fh.forms Cloud API.

//NodeJS Events Module. Note, this is required to register event emitter objects to forms.
var events = require('events');
var submissionEventListener = new events.EventEmitter();

$fh.forms.registerListener(submissionEventListener, function(err){
  if (err) return handleError(err);

  //submissionEventListener has now been registered with the $fh.forms Cloud API. Any valid Forms Events will now emit.
  submissionEventListener.on('submissionStarted', function(params){
    var submissionId = params.submissionId;
    console.log("Submission with ID " + submissionId + " has started");
  });

  //Removing the listener from the $fh.forms Cloud API.
  $fh.forms.deregisterListener(submissionEventListener);
});

3.16. $fh.forms.exportCSV

Note

The version of fh-mbaas-api in your package.json file must be at least 5.10.0.

3.16.1. Details

Export CSV files from the $fh.forms Cloud API. The export returns a zip file of several CSV files. To filter then use the input value, you can filter by:

  • projectId: The GUID of a project to filter by.
  • submissionId: A single Submission ID or an array of submission IDs to filter by.
  • formId: A single Form ID or and array of form IDs to filter by.
  • fieldHeader: Header text to use in the exported CSV files. The options are name for the name of the field or fieldCode to use the field code defined in the Form Builder.
// This is the input parameter to filter the list of CSV files.
var queryParams = {
  projectId: "projectId",
  submissionId: "submissionId",
  formId: ["formId1", "formId2"],
  fieldHeader: "name"
};

$fh.forms.exportCSV(queryParams, function(err, fileStreamObject) {
  // fileStreamObject is a zip file containing CSV files associated
  // to the form it was submitted against.
  if (err) return handleError(err);
  /**
  * Pipe the file stream to a writable stream (for example, a FileWriter)
  */
  fileStreamObject.pipe(writable_stream);
  fileStreamObject.resume();
});

3.17. $fh.forms.exportSinglePDF

Note

The version of fh-mbaas-api in your package.json file must be at least 5.12.0.

Note

This API is compatible with MBaaS version >=4.1.0 .

3.17.1. Details

Export one PDF file for a given submission from the $fh.forms Cloud API. The export returns a stream file.

var params = {
  submissionId: "submissionId"
};

$fh.forms.exportSinglePDF(params, function(err, fileStreamObject){
  if (err) return handleError(err);
  /**
  * Pipe the file stream to a writable stream (for example, a FileWriter)
  */
  fileStreamObject.pipe(writable_stream);
  fileStreamObject.resume();
});

Chapter 4. $fh.hash

$fh.hash(options, callback)

Generate the hash value of a given input.

4.1. Example

var options = {
  "algorithm": 'SHA256', // Possible values: MD5 | SHA1 | SHA256 | SHA512
  "text": 'Need more widgets'
};
$fh.hash(options, function (err, result) {
  if (err) {
    return console.error("Failed to generate hash value: " + err);
  } else {
    return console.log("Hash value is :" + result.hashvalue);
  }
});

Chapter 5. $fh.host

$fh.host(callback);

Fetch the public host name of the MBaaS. Useful for configuring callback URLs in various authentication libraries.

5.1. Example

// Fetch our own host
$fh.host(function (err, host) {
  if (err) return console.error(err);

  console.log('Host: ', host);
});

Chapter 6. $fh.push

$fh.push(message, options, callback(err, res))

Send a push message from the cloud to registered clients.

6.1. Example

Push a message to all devices in all Client Apps of the associated project

var message = {
  alert: "hello from FH"
}, options = {
    broadcast: true
};

$fh.push(message, options,
  function (err, res) {
    if (err) {
      console.log(err.toString());
    } else {
      console.log("status : " + res.status);
    }
  });

Push a message for specific deviceType in a specific Client App

var message = {
  alert: "hello from FH"
},
  options = {
    apps: ["3uzl1ebi6utciy56majgqlj8"], // list of App IDs
    criteria: {
      deviceType: "android"
    }
  };
$fh.push(message, options,
  function (err, res) {
    if (err) {
      console.log(err.toString());
    } else {
      console.log("status : " + res.status);
    }
  });

6.2. Example Silent Push (iOS only)

Cloud App Example:

var message = {
  'apns' : {
    'contentAvailable' :1
  }
};

var options = {
  broadcast: true,
};

$fh.push(message, options, function (err, res) {
  if (err) {
    console.log('Push error:' + err.toString());
  } else {
    console.log("status from Unified Push : " + util.inspect(res));
  }
});

Client App (Cordova) Example:

onNotification: function (event) {
  // content-available: 1 means Silent Notification
  if (event['content-available'] === 1) {
    //get the content and inform about the result
    var push = window.push;
    // call the fetchCompletionHandler not to terminate this app.
    push.setContentAvailable(push.FetchResult.NewData);
  }
}

Example of Log Output:

Sep 21 11:00:19 device_name SimpleCordovaPushApp[2192] <Warning>: Background Fetch
Sep 21 11:00:19 device_name SimpleCordovaPushApp[2192] <Warning>: didReceiveNotification
Sep 21 11:00:19 device_name SimpleCordovaPushApp[2192] <Warning>: Notification received

6.3. Parameters

6.3.1. Notification

  • message Object

    • alert String — The main message
    • sound String — The name of a sound file in the app bundle, or default
    • badge String — The number to display as the badge of the app icon
    • userData Object — Any extra user data to be passed
Note

For iOS, the sound triggers when the push notification is delivered to the client device. For Android, it triggers when the push notification is opened on the client device.

6.3.2. iOS-specific

  • message.apns Object — Options specific to the Apple Push Notification Service

    • title String — A short string describing the purpose of the notification
    • action String — The label of the action button
    • urlArgs Array — (Safari only) Values that are paired with the placeholders inside the urlFormatString value of your website.json file
    • titleLocKey String —  (iOS only) The key to a title string in the Localizable.strings file for the current localization
    • titleLocArgs Array — (iOS only) Variable string values to appear in place of the format specifiers in title-loc-key
    • actionCategory String — The identifier of the action category for the interactive notification
    • contentAvailable Number — (iOS only) Informs the application that new content is available by delivering a silent notification. The only possible value is 1.

6.3.3. Other configuration

  • options Object
  • options.config Object

    • ttl Number — (APNS and GCM only) The time to live in seconds.

6.3.4. Selection of Client Apps in project

Warning

One of the options — broadcast or apps — must be set manually, there is no default value.

  • options.broadcast Boolean — when set to true, notification will be sent to all Client Apps in the project which contains the sending Cloud App
  • options.apps Array — list of Client App IDs to send the notification to

6.3.5. Filtering recipients

  • options.criteria Object — Criteria for selection of notification recipients.
    See Sending Notifications for details about these criteria.

    • alias Array — list of user-specific identifiers
    • categories Array — list of categories
    • deviceType Array — list of device types
    • variants Array — list of variant IDs

6.3.6. Response handling

  • callback(err, res) Function — callback invoked after the message is pushed to the integrated push server. If err is set, it contains any possible error response. Parameter res contains the normal server response.

Chapter 7. $fh.sec

$fh.sec(options, callback)

Key generation, data encryption and decryption.

7.1. Example

RSA Key Generation

$fh.sec({
  "act": 'keygen',
  "params": {
    "algorithm": "RSA", // RSA or AES
    "keysize": 1024 // 1024 or 2048 for RSA
  }
}, function (err, res) {
  if (err) {
    return console.log("RSA key generation failed. Error: " + err);
  }
  return console.log("Public key is " + res.public + " Private key is " + res.private + ' Modulu is ' + res.modulu);
});

RSA Encryption

$fh.sec({
  "act": 'encrypt',
  "params": {
    "algorithm": "RSA", // padding: PKCS#1
    "plaintext": "Need more starting pages",
    "public": pubkey
  }
}, function (err, result) {
  if (err) {
    return console.log("Encryption failed: " + err);
  }
  return console.log("Encrypted data is " + result.ciphertext);
});

RSA Decryption

$fh.sec({
  "act": 'decrypt',
  "params": {
    "algorithm": "RSA",
    "ciphertext": "23941A28432482E374102FF48723BCB9847324",
    "private": privatekey
  }
}, function (err, result) {
  if (err) {
    return console.log("Decryption failed: " + err);
  }
  return console.log("Decryption data is " + result.plaintext);
});

AES Key Generation

$fh.sec({
  "act": 'keygen',
  "params": {
    "algorithm": "AES", // AES or RSA
    "keysize": 128 // 128 or 256 for AES
  }
}, function (err, res) {
  if (err) {
    return console.log("AES key generation failed. Error: " + err);
  }
  return console.log("AES secret key is " + res.secretkey + " Initialisation Vector is " + res.iv);
});

AES Encryption

$fh.sec({
  "act": 'encrypt',
  "params": {
    "algorithm": "AES", // mode : CBC, padding: PKCS#5
    "plaintext": "Need more starting pages",
    "key": secretkey,
    "iv": iv
  }
}, function (err, result) {
  if (err) {
    return console.log("Encryption failed: " + err);
  }
  return console.log("Encrypted data is " + result.ciphertext);
});

AES Decryption

$fh.sec({
  "act": 'decrypt',
  "params": {
    "algorithm": "AES",
    "ciphertext": "23941A28432482E374102FF48723BCB9847324",
    "key": secretkey,
    "iv": iv
  }
}, function (err, result) {
  if (err) {
    return console.log("Decryption failed: " + err);
  }
  return console.log("Decryption data is " + result.plaintext);
});

Chapter 8. $fh.service

$fh.service(options, callback);

Call an endpoint in an MBaaS Service.

Minimum Requirements

8.1. Example

var $fh = require('fh-mbaas-api');

$fh.service({
  "guid" : "0123456789abcdef01234567", // The 24 character unique id of the service
  "path": "/hello", //the path part of the url excluding the hostname - this will be added automatically
  "method": "POST",   //all other HTTP methods are supported as well. for example, HEAD, DELETE, OPTIONS
  "params": {
    "hello": "world"
  }, //data to send to the server - same format for GET or POST
  "timeout": 25000, // timeout value specified in milliseconds. Default: 60000 (60s)
  "headers" : {
    // Custom headers to add to the request. These will be appended to the default headers.
  }
}, function(err, body, res) {
  console.log('statuscode: ', res && res.statusCode);
  if ( err ) {
    // An error occurred during the call to the service. log some debugging information
    console.log('service call failed - err : ', err);
  } else {
    console.log('Got response from service - status body : ', res.statusCode, body);
  }
});

Chapter 9. $fh.stats

Utilise temporary stats counters and timers, which can then be viewed as graphs in the Studio.

9.1. Example

// Increment a counter.
// The name for the counter you want to increment.
// If this doesn't exist, it is created, and starts at 0.
var counter = 'my_counter';
$fh.stats.inc(counter);

// Decrement a counter
$fh.stats.dec(counter);

// Record a timer value
// The name for the timer you want to record a value for.
// If it doesn't exist, it is created.
var timer_name = 'my_timer';
// Timing in milliseconds of the interval you wish to record
// (for example, time difference between a timer start and end)
var time_in_ms = 500;
$fh.stats.timing(timer_name, time_in_ms);

Chapter 10. $fh.sync

The cloud sync framework requires handler functions to be defined which provide access to the back end data & manage data collisions. These are specified in the handleXXX() functions. Each unique dataset being managed is identified by a dataset_id which must be specified as the first parameter when calling any function of the sync framework.

Note

Default implementations of the handler functions are already provided as part of the MBaaS service. They use hosted db service to save data (via $fh.db). If this is enough for your app, you don’t need to implement the handler functions anymore, you just need to call the init function and provide sync options.

However, if the default implementations do not meet your app’s requirement (e.g you need to save data to somewhere else), you need to provide your own implementations of the handler functions listed below. You can provide implementations for all the CRUDL operations, or you can change the default behaviour of a particular operation by only providing an override for the corresponding handler function (e.g provide an override $fh.sync.handleRead function will allow you to implement your own read data logic, but keep the rest operations to still use the default MBaaS implementations).

The following table outlines the changes to the APIs relating to the introduction of fh-mbaas-api version 7 in this release. You can continue to use the pre 7.0.0 version, and the old documentation is still available.

API7.0.0 or laterpre 7.0.0

$fh.sync.setConfig

New

N/A

$fh.sync.connect

New

N/A

$fh.sync.init

Unchanged

Old documentation

$fh.sync.invoke

Unchanged

Old documentation

$fh.sync.stop

Unchanged

Old documentation

$fh.sync.stopAll

Unchanged

Old documentation

$fh.sync.handleList

Changed

Old documentation

$fh.sync.globalHandleList

Changed

Old documentation

$fh.sync.handleCreate

Changed

Old documentation

$fh.sync.globalHandleCreate

Changed

Old documentation

$fh.sync.handleRead

Changed

Old documentation

$fh.sync.globalHandleRead

Changed

Old documentation

$fh.sync.handleUpdate

Changed

Old documentation

$fh.sync.globalHandleUpdate

Changed

Old documentation

$fh.sync.handleDelete

Changed

Old documentation

$fh.sync.globalHandleDelete

Changed

Old documentation

$fh.sync.handleCollision

Unchanged

Old documentation

$fh.sync.globalHandleCollision

Unchanged

Old documentation

$fh.sync.listCollisions

Changed

Old documentation

$fh.sync.globalListCollisions

Changed

Old documentation

$fh.sync.removeCollision

Changed

Old documentation

$fh.sync.globalRemoveCollision

Changed

Old documentation

$fh.sync.setGlobalHashFn

New

N/A

$fh.sync.setRecordHashFn

New

N/A

$fh.sync.interceptRequest

Changed

Old documentation

$fh.sync.globalInterceptRequest

Changed

Old documentation

$fh.sync.getEventEmitter

New

N/A

10.1. $fh.sync.setConfig

Configure the sync server.

Call this API when the sync server is ready, but before initialising any of the datasets. Initialisation of a Dataset typically happens when the first Sync client connects, unless you have explicit calls to sync.init. Either way, a reasonable location to call setConfig is when the sync:ready event triggers.

10.1.1. Usage

$fh.sync.setConfig(options)

10.1.2. Parameters

10.1.2.1. options

  • Description: Configuration options for the sync server
  • Type: Object
  • Supported Keys

    • pendingWorkerInterval

      • Description: Set the interval value for the pending workers, in milliseconds. For more details about the worker interval, see the Data Sync Configuration Guide.
      • Type: Number
      • Default: 1
    • pendingWorkerBackoff

      • Description: Specify the backoff strategy for the pending workers. For more details about the worker backoff, see the Data Sync Configuration Guide.
      • Type: Object
      • Default: {strategy: 'exp', max: 60000}

        • strategy

          Define the backoff strategy. Valid values are exp (exponential) and fib (fibonacci). Setting the value to anything else disables worker backoff.

        • max

          The max delay time for the backoff strategy, in milliseconds.

    • pendingWorkerConcurrency

      • Description: Set the number of concurrent pending workers. Set it to 0 will disable the pending workers.
      • Type: Number
      • Default: 1
    • ackWorkerInterval

      • Description: Set the interval value for the ack workers, in milliseconds. For more details about the worker interval, see the Data Sync Configuration Guide.
      • Type: Number
      • Default: 1
    • ackWorkerBackoff

      • Description: Specify the backoff strategy for the ack workers. For more details about the worker backoff, see the Data Sync Configuration Guide.
      • Type: Object
      • Default: {strategy: 'exp', max: 60000}

        • strategy

          Define the backoff strategy. Valid values are exp (exponential) and fib (fibonacci). Setting it to anything else disables the backoff strategy for the ack workers.

        • max

          The max delay time for the backoff strategy, in milliseconds.

    • ackWorkerConcurrency

      • Description: Set the number of concurrent ack workers. Setting it to 0 disables the ack workers.
      • Type: Number
      • Default: 1
    • syncWorkerInterval

      • Description: Set the interval value for the sync workers, in milliseconds. For more details about the worker interval, see the Data Sync Configuration Guide.
      • Type: Number
      • Default: 100
    • syncWorkerBackoff

      • Description: Specify the backoff strategy for the sync workers. For more details about the worker backoff, see the Data Sync Configuration Guide.
      • Type: Object
      • Default: {strategy: 'none'}

        • strategy

          Define the backoff strategy. Valid values are exp (exponential) and fib (fibonacci). Setting it to anything else disables the backoff strategy.

        • max

          The max delay time for the backoff strategy, in milliseconds.

    • syncWorkerConcurrency

      • Description: Set the number of concurrent sync workers. Setting it to 0 disables the sync workers.
      • Type: Number
      • Default: 1
    • collectStats

      • Description: Determine if the sync server collects performance stats data.

        By default, the sync server collects some performance data, for example, db operation timing, API timing, queue size.

        The stats data is stored in Redis and has minimum performance overhead.

      • Type: Boolean
      • Default: true
    • statsRecordsToKeep

      • Description: Determine how many stats data points to save for each metric series in Redis.
      • Type: Number
      • Default: 1000
    • collectStatsInterval

      • Description: Determine how often the stats should be collected, in milliseconds.
      • Type: Number
      • Default: 5000
    • metricsInfluxdbHost

      • Description: Specify the InfluxDB host to which the sync server sends performance data.
      • Type: String
      • Default: null
    • metricsInfluxdbPort

      • Description: Specify the InfluxDB port. It must be a UDP port.
      • Type: Number
      • Default: null
    • queueMessagesTTL

      • Description: The time to live value for the queue messages that are marked for deletion. The messages are removed from the database once TTL value is reached. In seconds.
      • Type: Number
      • Default: 86400 (1 day)
    • datasetClientCleanerRetentionPeriod

      • Description: Specify how long an inactive datasetClient is kept in the database before it is deleted.

        To avoid unnessary deletion of datasetClients, consider overriding this configuration with a value that is appropriate for the app. For example, if there is no user using the app during the weekend, you could set this value to '96h'.

      • Type: String
      • Default: '24h'

        • Other supported units including: s (second), m (minute), h (hour), d (day), w (week), y (year)
    • datasetClientCleanerCheckFrequency

      • Description: Specify how often the datasetClient cleaner job runs.
      • Type: String
      • Default: '1h'
    • useCache

      • Description: Specify if Redis is used to cache the records of a Dataset Client.

        When enabled, it should reduce the number of requests on the database, and reduce the time of the syncRecords API call.

        It is an experimental feature and may cause delay for changes to be visible to all clients.

      • Type: Boolean
      • Default: false
    • schedulerInterval

      • Description: set the interval for the sync scheduler, in milliseconds.

        Typically, you do not need to change the value.

      • Type: Number
      • Default: 500
    • schedulerLockName

      • Description: A lock is used to make sure that only 1 sync scheduler can run at any given time. This field determines the name of that lock.

        Typically, you do not need to change the value.

      • Type: String
      • Default: locks:sync:SyncScheduler
    • schedulerLockMaxTime

      • Description: A lock is used to make sure that only 1 sync scheduler can run at any given time. This field determines the maximum time the sync scheduler can hold the lock for. This is to prevent the sync scheduler from holding the lock forever (for example, if the process crashes).

        Typically, you do not need to change the value.

      • Type: Number
      • Default: 20000
    • datasetClientUpdateConcurrency

      • Description: When there are a lot concurrent sync requests to the sync server, a lot of update operations to the Dataset Clients are generated. To avoid overloading the database, those operations are queued and then performed with the concurrency of this option.

        Typically, you do not need to change the value.

      • Type: Number
      • Default: 10

10.1.3. Example

$fh.events.on('sync:ready', function(){
  var pendingWorkerInterval = process.env.PENDING_WORKER_INTERVAL || 500;
  var syncWorkerInterval = process.env.SYNC_WORKER_INTERVAL || 500;
  var ackWorkerInterval = process.env.ACK_WORKER_INTERVAL || 500;
  var useCache = process.env.USE_CACHE === 'true';
  var syncConfig = {
    pendingWorkerInterval: parseInt(pendingWorkerInterval),
    ackWorkerInterval: parseInt(ackWorkerInterval),
    syncWorkerInterval: parseInt(syncWorkerInterval),
    collectStatsInterval: 4000,
    metricsInfluxdbHost: process.env.METRICS_HOST,
    metricsInfluxdbPort: parseInt(process.env.METRICS_PORT),
    useCache: useCache
  };
  $fh.sync.setConfig(syncConfig);
});

10.2. $fh.sync.connect

Make sure the sync server is connected to the required resources, that is, MongoDB and Redis.

Note

When using the sync server from fh-mbaas-api, sync.connect is called automatically, and uses the Cloud App’s database. There is no need to call sync.connect in this scenario.

10.2.1. Usage

$fh.sync.connect(mongodbConnectionString, mongodbConf, redisConnectionString, callback)

10.2.2. Parameters

10.2.2.1. mongodbConnectionString

  • Description: The connection url of MongoDB. The url is passed straight to the mongodb module.
  • Type: String

10.2.2.2. mongodbConf

  • Description: The MongoDB connection options. For more details of this option, see MongoClient.connect API doc.

    Typically, you do not need to call this API. However, you can control some of the MongoDB connection options using environment variables:

    • SYNC_MONGODB_POOLSIZE

      • Description: Specify the MongoDB connection pool size
      • Type: Number
      • Default: 50
  • Type: Object

10.2.2.3. redisConnectionString

  • Description: The connection URL of Redis, which can include authentication information if required. The URL is passed directly to the redis module.
  • Type: String

10.2.2.4. callback

  • Description: the callback function
  • Type: function

10.2.3. Example

var mongodbUrl = "mongodb://mongouser:mongopass@127.0.0.1";
var redisUrl = "redis://redisuser:redispass@127.0.0.1";

$fh.sync.connect(mongodbUrl, {}, redisUrl, function(err){
  if (err) {
    console.error('Connection error for sync', err);
  } else {
    console.log('sync connected');
  }
});

10.3. $fh.sync.init

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Set the sync options for the Dataset and start the sync process. This API can also be used to start the sync process on a Dataset.

This API call is optional, but can be used to override options for a specific Dataset.

10.3.1. Usage

$fh.sync.init(dataset_id, options, callback)

10.3.2. Parameters

10.3.2.1. dataset_id

  • Description: The id of the dataset that needs to be synchronized.
  • Type: String

10.3.2.2. options

  • Description: The sync options for the Dataset.
  • Type: Object
  • Supported Keys:

    • syncFrequency

    • clientSyncTimeout

      • Description: Specify the period of time before the Dataset client is marked as "inactive" due to inactivity, in seconds.

        If a Dataset client is marked as "inactive", the sync server stops syncing the data of the Dataset client with the backend.

        If a user accesses an "inactive" Dataset client later, the user might need to wait until the next sync operation is complete. To avoid this scenario, set this timeout to a relatively long value.

      • Type: Number
      • Default: 3600 (1 hour)
    • backendListTimeout

      • Description: Specify the timeout value the sync server waits for the sync operation with the Backend Database to complete, in seconds.
      • Type: Number
      • Default: 300

10.3.2.3. callback

  • Description: The callback function invoked when fh.init is complete.
  • Type: Function

10.3.3. Example

var datasetId = "todolist";
var syncOptions = {
  syncFrequency: 10,
  clientSyncTimeout: 24*60*60
};
$fh.sync.init(datasetId, syncOptions, function(err){
  if (err) {
    console.error('sync init failed due to error', err);
  } else {
    console.log('sync init finished successfully');
  }
});

10.3.4. $fh.sync.init for fh-mbaas-api Version Less than 7.0.0

$fh.sync.init(dataset_id, options, callback)

Initialise cloud data sync service for specified dataset.

10.3.4.1. Example

// Unique Id for the dataset to initialise.
var dataset_id = 'tasks';
// Configuration options
var options = {
  "syncFrequency": 10, // How often to synchronise data with the back end data store in seconds. Default: 10s
  "logLevel":"info" // The level of logging. Can be usful for debugging. Valid options including: 'silly', 'verbose', 'info', 'warn', 'debug', 'error'
};
$fh.sync.init(dataset_id, options, function(err) {
  // Check for any error thrown during initialisation
  if (err) {
    console.error(err);
  } else {
    //you can now provide data handler function overrides (again, not required at all). For example,
    $fh.sync.handleList(dataset_id, function(dataset_id, params, cb, meta_data){
      //implement the data listing logic
    });
  }
});

10.4. $fh.sync.invoke

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Invoke internal sync functions of the sync server. Typical development does not require you to invoke these functions. Note that the params object is the same as the request body from Sync clients, because this API is called by Sync clients.

10.4.1. Usage

$fh.sync.invoke(dataset_id, params, callback)

10.4.2. Parameters

10.4.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.4.2.2. params

  • Description: Specify the target function name, also passed to the target function.
  • Type: Object
  • Supported Keys:

    • fn

      • Description: specify the name of the target function to invoke. Supported functions including:

        • sync
        • syncRecords
        • listCollisions
        • removeCollision
      • Type: String
    • Other fields vary depending on the target function. Please check the source code for the required fields.

10.4.3. Example

var datasetId = "todo";
var syncRecordsParams = {
  fn: 'syncRecords',
  dataset_id: datasetId,
  query_params: {},
  clientRecs: {},
  __fh: {
    cuid: 'testdeviceid'
  }
};

$fh.sync.invoke(datasetId, syncRecordsParams, function(err, syncData) {
  if (err) {
    console.error('Failed to call syncRecords due to error', err);
  } else {
    console.log('Got sync data', syncData);
  }
});

10.4.4. $fh.sync.invoke for fh-mbaas-api Version Less than 7.0.0

$fh.sync.invoke(dataset_id, params, callback)

Invoke the Sync Server.

10.4.4.1. Example

// This should be called from a cloud “act” function.
// The params passed to the “act” function:
var params = {
  "limit": 50
};
$fh.sync.invoke(dataset_id, params, function() {
  // "act" function callback
});

10.5. $fh.sync.stop

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Stop the synchronization of a specific Dataset with the Dataset Backend.

10.5.1. Usage

$fh.sync.stop(dataset_id, callback)

10.5.2. Parameters

10.5.2.1. dataset_id

  • Description: The id of the dataset.
  • Type: String

10.5.2.2. callback

  • Description: The callback function.
  • Type: Function

10.5.3. Example

var datasetId = "todolist";
$fh.sync.stop(datasetId, function(err){
  if (err) {
    console.error('sync stop failed due to error', err);
  } else {
    console.log('sync stop finished successfully');
  }
});

10.5.4. $fh.sync.stop for fh-mbaas-api Version Less than 7.0.0

$fh.sync.stop(dataset_id, callback)

Stop cloud data sync for the specified dataset_id.

10.5.4.1. Example

// This will remove any reference to the dataset from the sync service.
// Any subsequent cloud calls to sync.invoke will fail with an unknown_dataset error.
// The dataset can be put back under control of the sync service by calling the
// sync.init() function again.
// Calling stop on a non-existent dataset has no effect.
// Calling stop multiple times on the same dataset has no effect.
$fh.sync.stop(dataset_id, function() {
  // Callback to invoke once the dataset has been removed from the management
  // of the service.
  // There are no parameters passed to this callback.
});

10.6. $fh.sync.stopAll

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Stop the synchronization of all Datasets with the Dataset Backend.

10.6.1. Usage

$fh.sync.stopAll(callback)

10.6.2. Parameters

10.6.2.1. callback

  • Description: The callback function.
  • Type: Function

10.6.3. Example

$fh.sync.stopAll(function(err){
  if (err) {
    console.error('sync stopAll failed due to error', err);
  } else {
    console.log('sync stopAll finished successfully');
  }
});

10.6.4. $fh.sync.stopAll for fh-mbaas-api Version Less than 7.0.0

$fh.sync.stopAll(callback)

Stop cloud data sync service for ALL datasets.

10.6.4.1. Example

// This will remove all reference to all datasets from the sync service.
// Any subsequent cloud calls to sync.invoke() will fail with an unknown_dataset error.
// Any of the datasets can be put back under control of the sync service by calling
// the sync.init() function again and passing the required dataset_id.
// Calling stop multiple times has no effect -
// except that the return data to the callback (an array of dataset_ids which are no longer being synced) will be different.
$fh.sync.stopAll(function(err, res) {
  if (err) console.error(err); // Any error thrown during the removal of the datasets

  // A JSON Array of Strings - representing the dataset_Ids which have been
  // removed from the sync service.
  console.log(res);
});

10.7. $fh.sync.handleList

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a handler function listing data from the Dataset Backend for a specific Dataset.

Note

Make sure the returned data is valid JSON objects. For example, a Date object is not valid in a JSON Object.

Note

Make sure there is no _id field in the returned data (or any of the nested objects). MongoDB does not save data that contains the _id field.

10.7.1. Usage

$fh.sync.handleList(dataset_id, function listHandler(dataset_id, query_params, meta_data, cb){});

10.7.2. Parameters

10.7.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.7.2.2. listHandler

  • Description: The function that is invoked when listing records
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • query_params

      • Description: the query parameter to use as part of the list, can be null.
      • Type: Object
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.7.3. Example

$fh.sync.handleList("todo", function(dataset_id, params, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // JSON object representing query parameters passed from the client.
  // These can be used to restrict the data set returned.
  console.log(params);

  // The callback into the sync service to store the dataset
  // cb(err, data)
  cb(null, { // A JSON Object - representing the data
    uid_1 : {/* data */},
    uid_2 : {/* data */},
    uid_3 : {/* data */}
  });
});

// It is recommended that the handleList function converts data from the back end
// format into a full JSON Object.
// This is a sensible approach when reading data from relational and nonrelational
// databases, and works well for SOAP and XML data.
// However, it may not always be feasible - for example, when reading non structured data.
// In these cases, the recomened approach is to create a JSON object with a single
// key called “data” and set the value for this key to be the actual data.
// for example, xml data
/*
<dataset>
  <row>
    <userid>123456</userid>
    <firstname>Joe</firstname>
    <surname>Bloggs</surname>
    <dob>1970-01-01</dob>
    <gender>male</gender>
  </row>
</dataset>
*/
/* json data
{
  "123456" : {
    "userid" : "123456",
    "firstname" : "Joe",
    "surname" : "Bloggs",
    "dob" : "1970-01-01",
    "gender" : "male"
  }
}
*/

// And for non structured data:
/*
123456|Joe|Bloggs|1970-01-01|male

{
  "123456" : {
    "data" : "123456|Joe|Bloggs|1970-01-01|male"
  }
}
*/

10.7.4. $fh.sync.handleList for fh-mbaas-api Version Less than 7.0.0

$fh.sync.handleList(dataset_id, callback)

Defines a handler function for listing data from the back end data source for a dataset. Call this API after the dataset is initialized.

10.7.4.1. Example

$fh.sync.handleList(dataset_id, function(dataset_id, params, cb, meta_data) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // JSON object representing query parameters passed from the client.
  // These can be used to restrict the data set returned.
  console.log(params);

  // The callback into the sync service to store the dataset
  // cb(err, data)
  cb(null, { // A JSON Object - representing the data
    uid_1 : {/* data */},
    uid_2 : {/* data */},
    uid_3 : {/* data */}
  });
});
// It is recommended that the handleList function converts data from the back end
// format into a full JSON Object.
// This is a sensible approach when reading data from relational and nonrelational
// databases, and works well for SOAP and XML data.
// However, it may not always be feasible - for example, when reading non structured data.
// In these cases, the recomened approach is to create a JSON object with a single
// key called “data” and set the value for this key to be the actual data.
// for example, xml data
/*
<dataset>
  <row>
    <userid>123456</userid>
    <firstname>Joe</firstname>
    <surname>Bloggs</surname>
    <dob>1970-01-01</dob>
    <gender>male</gender>
  </row>
</dataset>
*/
/* json data
{
  "123456" : {
    "userid" : "123456",
    "firstname" : "Joe",
    "surname" : "Bloggs",
    "dob" : "1970-01-01",
    "gender" : "male"
  }
}
*/

// And for non structured data:
/*
123456|Joe|Bloggs|1970-01-01|male

{
  "123456" : {
    "data" : "123456|Joe|Bloggs|1970-01-01|male"
  }
}
*/

10.8. $fh.sync.globalHandleList

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a global handler function for listing data from the Dataset Backend.

It can be used by multiple datasets, but typically, is only used if there is no handler assigned to the dataset using the handleList API.

Note

Make sure the returned data is valid JSON objects. For example, a Date object is not valid in a JSON Object.

Note

Make sure there is no _id field in the returned data (or any of the nested objects). MongoDB does not save data that contains the _id field.

10.8.1. Usage

$fh.sync.globalHandleList(function listHandler(dataset_id, query_params, meta_data, cb){});

10.8.2. Parameters

10.8.2.1. listHandler

  • Description: The function that is invoked when listing records
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • query_params

      • Description: the query parameter to use as part of the list, can be null.
      • Type: Object
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.8.3. Example

$fh.sync.globalHandleList(function(dataset_id, params, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // JSON object representing query parameters passed from the client.
  // These can be used to restrict the data set returned.
  console.log(params);

  // The callback into the sync service to store the dataset
  // cb(err, data)
  cb(null, { // A JSON Object - representing the data
    uid_1 : {/* data */},
    uid_2 : {/* data */},
    uid_3 : {/* data */}
  });
});

// It is recommended that the handleList function converts data from the back end
// format into a full JSON Object.
// This is a sensible approach when reading data from relational and nonrelational
// databases, and works well for SOAP and XML data.
// However, it may not always be feasible - for example, when reading non structured data.
// In these cases, the recomened approach is to create a JSON object with a single
// key called “data” and set the value for this key to be the actual data.
// for example, xml data
/*
<dataset>
  <row>
    <userid>123456</userid>
    <firstname>Joe</firstname>
    <surname>Bloggs</surname>
    <dob>1970-01-01</dob>
    <gender>male</gender>
  </row>
</dataset>
*/
/* json data
{
  "123456" : {
    "userid" : "123456",
    "firstname" : "Joe",
    "surname" : "Bloggs",
    "dob" : "1970-01-01",
    "gender" : "male"
  }
}
*/

// And for non structured data:
/*
123456|Joe|Bloggs|1970-01-01|male

{
  "123456" : {
    "data" : "123456|Joe|Bloggs|1970-01-01|male"
  }
}
*/

10.8.4. $fh.sync.globalHandleList for fh-mbaas-api Version Less than 7.0.0

$fh.sync.globalHandleList(callback)

Similar to $fh.sync.handleList, but set the handler globally which means the same handler function can be used by multiple datasets. The global handler will only be used if there is no handler assigned to the dataset via $fh.sync.handleList.

10.8.4.1. Example

$fh.sync.globalHandleList(function(dataset_id, params, cb, meta_data){
  //list data for the specified dataset_id
});

10.9. $fh.sync.handleCreate

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a handler function to create a single row of data in the Dataset Backend for a specific Dataset.

10.9.1. Usage

$fh.sync.handleCreate(dataset_id, function createHandler(dataset_id, data, meta_data, cb){});

10.9.2. Parameters

10.9.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.9.2.2. createHandler

  • Description: The function that is invoked when creating a record.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • data

      • Description: the data to create
      • Type: Object
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.9.3. Example

$fh.sync.handleCreate("todo", function(dataset_id, data, meta_data, cb){
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Row of data to create
  console.log(data);

  // Sample back-end storage call
  var savedData = saveData(data);
  var res = {
    "uid": savedData.uid, // Unique Identifier for row
    "data": savedData.data // The created data record - including any system or UID fields added during the create process
  };

  // Callback function for when the data has been created, or if theres an error
  return cb(null, res);
});

10.9.4. $fh.sync.handleCreate for fh-mbaas-api Version Less than 7.0.0

$fh.sync.handleCreate(dataset_id, callback)

Defines a handler function for creating a single row of data in the back end. Should be called after the dataset is inited.

10.9.4.1. Example

// data source for a dataset.
$fh.sync.handleCreate(dataset_id, function(dataset_id, data, cb, meta_data) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Row of data to create
  console.log(data);

  // Sample back-end storage call
  var savedData = saveData(data);
  var res = {
    "uid": savedData.uid, // Unique Identifier for row
    "data": savedData.data // The created data record - including any system or UID fields added during the create process
  };

  // Callback function for when the data has been created, or if theres an error
  return cb(null, res);
});

10.10. $fh.sync.globalHandleCreate

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a global handler function for creating a single row of data in the back end.

It can be used by multiple datasets, but is only used if there is no handler assigned to the dataset using the handleCreate API.

10.10.1. Usage

$fh.sync.globalHandleCreate(function createHandler(dataset_id, data, meta_data, cb){});

10.10.2. Parameters

10.10.2.1. createHandler

  • Description: The function that is invoked when creating a record.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • data

      • Description: the data to create
      • Type: Object
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.10.3. Example

$fh.sync.globalHandleCreate(function(dataset_id, data, meta_data, cb){
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Row of data to create
  console.log(data);

  // Sample back-end storage call
  var savedData = saveData(data);
  var res = {
    "uid": savedData.uid, // Unique Identifier for row
    "data": savedData.data // The created data record - including any system or UID fields added during the create process
  };

  // Callback function for when the data has been created, or if theres an error
  return cb(null, res);
});

10.10.4. $fh.sync.globalHandleCreate for fh-mbaas-api Version Less than 7.0.0

$fh.sync.globalHandleCreate(callback)

Similar to $fh.sync.handleCreate, but set the handler globally which means the same handler function can be used by multiple datasets. The global handler will only be used if there is no handler assigned to the dataset via $fh.sync.handleCreate.

10.10.4.1. Example

$fh.sync.globalHandleCreate(function(dataset_id, data, cb, meta_data){
  //create data for the specified dataset_id
});

10.11. $fh.sync.handleRead

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a handler function to read a single row of data from the Dataset Backend for a specific Dataset.

10.11.1. Usage

$fh.sync.handleRead(dataset_id, function readHandler(dataset_id, uid, meta_data, cb){});

10.11.2. Parameters

10.11.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.11.2.2. readHandler

  • Description: The function that is invoked when reading a record.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • uid

      • Description: the unique id of the record to read
      • Type: String
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.11.3. Example

$fh.sync.handleRead("todo", function(dataset_id, uid, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique Identifier for row to read
  console.log(uid);

  // Sample back-end storage call
  var data = readData(uid);
  /* sample response
    {
      "userid": "1234",
      "name": "Jane Bloggs",
      "age": 27
    }
  */

  // The callback into the sync service to return the row of data
  return cb(null, data);
});

10.11.4. $fh.sync.handleRead for fh-mbaas-api Version Less than 7.0.0

$fh.sync.handleRead(dataset_id, callback)

Defines a handler function for reading a single row of data from the back end. Should be called after the dataset is initialised.

10.11.4.1. Example

// data source for a dataset
$fh.sync.handleRead(dataset_id, function(dataset_id, uid, cb, meta_data) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique Identifier for row to read
  console.log(uid);

  // Sample back-end storage call
  var data = readData(uid);
  /* sample response
    {
      "userid": "1234",
      "name": "Jane Bloggs",
      "age": 27
    }
  */

  // The callback into the sync service to return the row of data
  return cb(null, data);
});

10.12. $fh.sync.globalHandleRead

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a global handler function to read a single row of data from the Dataset Backend.

It can be used by multiple datasets, but is only used if there is no handler assigned to the dataset using the handleRead API.

10.12.1. Usage

$fh.sync.globalHandleRead(function readHandler(dataset_id, uid, meta_data, cb){});

10.12.2. Parameters

10.12.2.1. readHandler

  • Description: The function that is invoked when reading a record.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • uid

      • Description: the unique id of the record to read
      • Type: String
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.12.3. Example

$fh.sync.globalHandleRead(function(dataset_id, uid, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique Identifier for row to read
  console.log(uid);

  // Sample back-end storage call
  var data = readData(uid);
  /* sample response
    {
      "userid": "1234",
      "name": "Jane Bloggs",
      "age": 27
    }
  */

  // The callback into the sync service to return the row of data
  return cb(null, data);
});

10.12.4. $fh.sync.globalHandleRead for fh-mbaas-api Version Less than 7.0.0

$fh.sync.globalHandleRead(callback)

Similar to $fh.sync.handleRead, but set the handler globally which means the same handler function can be used by multiple datasets. The global handler will only be used if there is no handler assigned to the dataset via $fh.sync.handleRead.

10.12.4.1. Example

$fh.sync.globalHandleRead(function(dataset_id, uid, cb, meta_data){
  //read data for the specified dataset_id and uid
});

10.13. $fh.sync.handleUpdate

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a handler function to update a single row of data on the Dataset Backend for a specific Dataset.

The sync server makes sure the data can be updated by checking the current value matches the value in the back end. If the values do not match, the update operation is not be performed and a collision is generated.

10.13.1. Usage

$fh.sync.handleUpdate(dataset_id, function updateHandler(dataset_id, uid, data, meta_data, cb){});

10.13.2. Parameters

10.13.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.13.2.2. updateHandler

  • Description: The function that is invoked when updating a record.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • uid

      • Description: the unique id of the record to update
      • Type: String
    • data

      • Description: the new date fields
      • Type: Object
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.13.3. Example

$fh.sync.handleUpdate("todo", function(dataset_id, uid, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique Identifier for row to update
  console.log(uid);

  // Row of data to update
  console.log(data);

  // Sample back-end storage call
  var updatedData = updateData(uid, data);
  /* sample response
    {
      "userid": "1234",
      "name": "Jane Bloggs",
      "age": 27
    }
  */

  // The callback into the sync service to return the updated row of data
  return cb(null, updatedData);
});

10.13.4. $fh.sync.handleUpdate for fh-mbaas-api Version Less than 7.0.0

$fh.sync.handleUpdate(dataset_id, callback)

Defines a handler function for updating a single row of data from the back end. Should be called after the dataset is initialised.

10.13.4.1. Example

// data source for a dataset.
// The sync service will verify that the update can proceed
// (that is, collision detection) before it invokes the update function.
$fh.sync.handleUpdate(dataset_id, function(dataset_id, uid, data, cb, meta_data) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique Identifier for row to update
  console.log(uid);

  // Row of data to update
  console.log(data);

  // Sample back-end storage call
  var updatedData = updateData(uid, data);
  /* sample response
    {
      "userid": "1234",
      "name": "Jane Bloggs",
      "age": 27
    }
  */

  // The callback into the sync service to return the updated row of data
  return cb(null, updatedData);
});

10.14. $fh.sync.globalHandleUpdate

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a global handler function to update a single row of data on the Dataset Backend.

It can be used by multiple datasets, but is only used if there is no handler assigned to the dataset using the handleUpdate API.

The sync server makes sure the data can be updated by checking the current value matches the value in the Dataset Backend. If the values do not match, the update operation is not be performed and a collision is generated.

10.14.1. Usage

$fh.sync.globalHandleUpdate(function updateHandler(dataset_id, uid, data, meta_data, cb){});

10.14.2. Parameters

10.14.2.1. updateHandler

  • Description: The function that is invoked when updating a record.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • uid

      • Description: the unique id of the record to update
      • Type: String
    • data

      • Description: the new date fields
      • Type: Object
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.14.3. Example

$fh.sync.globalHandleUpdate(function(dataset_id, uid, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique Identifier for row to update
  console.log(uid);

  // Row of data to update
  console.log(data);

  // Sample back-end storage call
  var updatedData = updateData(uid, data);
  /* sample response
    {
      "userid": "1234",
      "name": "Jane Bloggs",
      "age": 27
    }
  */

  // The callback into the sync service to return the updated row of data
  return cb(null, updatedData);
});

10.14.4. $fh.sync.globalHandleUpdate for fh-mbaas-api Version Less than 7.0.0

$fh.sync.globalHandleUpdate(callback)

Similar to $fh.sync.handleUpdate, but set the handler globally which means the same handler function can be used by multiple datasets. The global handler will only be used if there is no handler assigned to the dataset via $fh.sync.handleUpdate.

10.14.4.1. Example

$fh.sync.globalHandleUpdate(function(dataset_id, uid, data, cb, meta_data){
  //update data for the specified dataset_id and uid
});

10.15. $fh.sync.handleDelete

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a handler function to delete a single row of data from the Dataset Backend for a specific Dataset. The sync server makes sure the data can be deleted, that is, the row is up to date and will not cause collisions.

10.15.1. Usage

$fh.sync.handleDelete(dataset_id, function deleteHandler(dataset_id, uid, meta_data, cb){});

10.15.2. Parameters

10.15.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.15.2.2. deleteHandler

  • Description: The function that is invoked when deleting a record.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • uid

      • Description: the unique id of the record to delete
      • Type: String
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.15.3. Example

$fh.sync.handleDelete("todo", function(dataset_id, uid, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique Identifier for row to update
  console.log(uid);

  // Sample back-end storage call
  var deletedData = deleteData(uid);

  /* sample response
    {
      "userid": "1234",
      "name": "Jane Bloggs",
      "age": 27
    }
  */

  // The callback into the sync service to return the deleted row of data
  return cb(null, deletedData);
});

10.15.4. $fh.sync.handleDelete for fh-mbaas-api Version Less than 7.0.0

$fh.sync.handleDelete(dataset_id, callback)

Defines a handler function for deleting a single row of data from the back end. Should be called after the dataset is initialised.

10.15.4.1. Example

// data source for a dataset.
// The sync service will verify that the delete can proceed
// (that is, collision detection) before it invokes the delete function.
$fh.sync.handleDelete(dataset_id, function(dataset_id, uid, cb, meta_data) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique Identifier for row to update
  console.log(uid);

  // Sample back-end storage call
  var deletedData = deleteData(uid);

  /* sample response
    {
      "userid": "1234",
      "name": "Jane Bloggs",
      "age": 27
    }
  */

  // The callback into the sync service to return the deleted row of data
  return cb(null, deletedData);
});

10.16. $fh.sync.globalHandleDelete

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a global handler function to delete a single row of data from the Dataset Backend.

It can be used by multiple datasets, but is only used if there is no handler assigned to the dataset using the handleDelete API.

The sync server makes sure the data can be deleted, that is, the row is up to date and will not cause collisions.

10.16.1. Usage

$fh.sync.globalHandleDelete(function deleteHandler(dataset_id, uid, meta_data, cb){});

10.16.2. Parameters

10.16.2.1. deleteHandler

  • Description: The function that is invoked when deleting a record.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • uid

      • Description: the unique id of the record to delete
      • Type: String
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.16.3. Example

$fh.sync.globalHandleDelete(function(dataset_id, uid, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique Identifier for row to update
  console.log(uid);

  // Sample back-end storage call
  var deletedData = deleteData(uid);

  /* sample response
    {
      "userid": "1234",
      "name": "Jane Bloggs",
      "age": 27
    }
  */

  // The callback into the sync service to return the deleted row of data
  return cb(null, deletedData);
});

10.16.4. $fh.sync.globalHandleDelete for fh-mbaas-api Version Less than 7.0.0

$fh.sync.globalHandleDelete(callback)

Similar to $fh.sync.handleDelete, but set the handler globally which means the same handler function can be used by multiple datasets. The global handler will only be used if there is no handler assigned to the dataset via $fh.sync.handleDelete.

10.16.4.1. Example

$fh.sync.globalHandleDelete(function(dataset_id, uid, cb, meta_data){
  //delete data for the specified dataset_id and uid
});

10.17. $fh.sync.handleCollision

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a handler function to deal with data collisions for a specific Dataset.

You can resolve the collision in this function, or just persist the collision somewhere for later review.

10.17.1. Usage

$fh.sync.handleCollision(dataset_id, function collisionHandler(dataset_id, hash, timestamp, uid, pre, post, meta_data){});

10.17.2. Parameters

10.17.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.17.2.2. collisionHandler

  • Description: The function that is invoked when a collision is generated.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • hash

      • Description: the unique hash value of the collision
      • Type: String
    • timestamp

      • Description: the timestamp when the change is generated on the client. In milliseconds.
      • Type: Number
    • uid

      • Description: the unique id of the pending record
      • Type: String
    • pre

      • Description: the data before the change
      • Type: Object
    • post

      • Description: the changed data
      • Type: Object
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object

10.17.3. Example

// Typically a collision handler will write the data record to a collisions table
// which is reviewed by a user who can manually reconcile the collisions.
$fh.sync.handleCollision("todo", function(dataset_id, hash, timestamp, uid, pre, post, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique hash value identifying the collision
  console.log(hash);

  // Date / time that update was created on client device
  console.log(timestamp);

  // Unique Identifier for row
  console.log(uid);

  // The data row the client started with
  console.log(pre);

  //The data row the client tried to write
  console.log(post);

  // sample back-end storage call
  saveCollisionData(dataset_id, hash, timestamp, uid, pre, post);
});

10.17.4. $fh.sync.handleCollision for fh-mbaas-api Version Less than 7.0.0

$fh.sync.handleCollision(dataset_id, callback)

Defines a handler function for dealing with data collisions (that is, stale updates). Should be called after the dataset is initialised.

10.17.4.1. Example

// Typically a collision handler will write the data record to a collisions table
// which is reviewed by a user who can manually reconcile the collisions.
$fh.sync.handleCollision(dataset_id, function(dataset_id, hash, timestamp, uid, pre, post, meta_data) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique hash value identifying the collision
  console.log(hash);

  // Date / time that update was created on client device
  console.log(timestamp);

  // Unique Identifier for row
  console.log(uid);

  // The data row the client started with
  console.log(pre);

  //The data row the client tried to write
  console.log(post);

  // sample back-end storage call
  saveCollisionData(dataset_id, hash, timestamp, uid, pre, post);
});

10.18. $fh.sync.globalHandleCollision

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a global handler function to deal with data collisions.

You can resolve the collision in this function, or just persist the collision somewhere for later review.

It can be used by multiple datasets, but is only used if there is no handler assigned to the dataset using the handleCollision API.

10.18.1. Usage

$fh.sync.globalHandleCollision(function collisionHandler(dataset_id, hash, timestamp, uid, pre, post, meta_data){});

10.18.2. Parameters

10.18.2.1. collisionHandler

  • Description: The function that is invoked when a collision is generated.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • hash

      • Description: the unique hash value of the collision
      • Type: String
    • timestamp

      • Description: the timestamp when the change is generated on the client. In milliseconds.
      • Type: Number
    • uid

      • Description: the unique id of the pending record
      • Type: String
    • pre

      • Description: the data before the change
      • Type: Object
    • post

      • Description: the changed data
      • Type: Object
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object

10.18.3. Example

// Typically a collision handler will write the data record to a collisions table
// which is reviewed by a user who can manually reconcile the collisions.
$fh.sync.globalHandleCollision(function(dataset_id, hash, timestamp, uid, pre, post, meta_data) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // Unique hash value identifying the collision
  console.log(hash);

  // Date / time that update was created on client device
  console.log(timestamp);

  // Unique Identifier for row
  console.log(uid);

  // The data row the client started with
  console.log(pre);

  //The data row the client tried to write
  console.log(post);

  // sample back-end storage call
  saveCollisionData(dataset_id, hash, timestamp, uid, pre, post);
});

10.18.4. $fh.sync.globalHandleCollision for fh-mbaas-api Version Less than 7.0.0

$fh.sync.globalHandleCollision(callback)

Similar to $fh.sync.handleCollision, but set the handler globally which means the same handler function can be used by multiple datasets. The global handler will only be used if there is no handler assigned to the dataset via $fh.sync.handleCollision.

10.18.4.1. Example

$fh.sync.globalHandleCollision(function(dataset_id, hash, timestamp, uid, pre, post, meta_data){

});

10.19. $fh.sync.listCollisions

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a handler function to return the current list of collisions for a Dataset.

10.19.1. Usage

$fh.sync.listCollisions(dataset_id, function listCollisionsHandler(dataset_id, meta_data, cb){});

10.19.2. Parameters

10.19.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.19.2.2. listCollisionsHandler

  • Description: The function that is invoked when listing collisions.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.19.3. Example

// This would usually be used by an administration console where a user is
// manually reviewing & resolving collisions.
$fh.sync.listCollisions("todo", function(dataset_id, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // sample back-end storage call
  var collisions = getCollisions(dataset_id);
  /* sample response:
  {
    "collision_hash_1" : {
      "uid": "<uid_of_data_row>",
      "timestamp": "<timestamp_value_passed_to_handleCollision_fn>",
      "pre": "<pre_data_record_passed_to_handleCollision_fn>",
      "post": "<post_data_record_passed_to_handleCollision_fn>"
    },
    "collision_hash_2" : {
      "uid": "<uid_of_data_row>",
      "timestamp": "<timestamp_value_passed_to_handleCollision_fn>",
      "pre": "<pre_data_record_passed_to_handleCollision_fn>",
      "post": "<post_data_record_passed_to_handleCollision_fn>"
    },
    "collision_hash_2" : {
      "uid": "<uid_of_data_row>",
      "timestamp": "<timestamp_value_passed_to_handleCollision_fn>",
      "pre": "<pre_data_record_passed_to_handleCollision_fn>",
      "post": "<post_data_record_passed_to_handleCollision_fn>"
    }
  }
  */

  // The callback into the sync service to return the list of known collisions
  return cb(null, collisions);
});

10.19.4. $fh.sync.listCollisions for fh-mbaas-api Version Less than 7.0.0

$fh.sync.listCollisions(dataset_id, callback)

Defines a handler function for returning the current list of collisions. Should be called after the dataset is initialised.

10.19.4.1. Example

// This would usually be used by an administration console where a user is
// manually reviewing & resolving collisions.
$fh.sync.listCollisions(dataset_id, function(dataset_id, cb, meta_data) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // sample back-end storage call
  var collisions = getCollisions(dataset_id);
  /* sample response:
  {
    "collision_hash_1" : {
      "uid": "<uid_of_data_row>",
      "timestamp": "<timestamp_value_passed_to_handleCollision_fn>",
      "pre": "<pre_data_record_passed_to_handleCollision_fn>",
      "post": "<post_data_record_passed_to_handleCollision_fn>"
    },
    "collision_hash_2" : {
      "uid": "<uid_of_data_row>",
      "timestamp": "<timestamp_value_passed_to_handleCollision_fn>",
      "pre": "<pre_data_record_passed_to_handleCollision_fn>",
      "post": "<post_data_record_passed_to_handleCollision_fn>"
    },
    "collision_hash_2" : {
      "uid": "<uid_of_data_row>",
      "timestamp": "<timestamp_value_passed_to_handleCollision_fn>",
      "pre": "<pre_data_record_passed_to_handleCollision_fn>",
      "post": "<post_data_record_passed_to_handleCollision_fn>"
    }
  }
  */

  // The callback into the sync service to return the list of known collisions
  return cb(null, collisions);
});
Note

"collision_hash" is the hash value which uniquely identifies a collision. This value will have been passed as the "hash" parameter when the collision was originally created in the "handleCollision" function.

10.20. $fh.sync.globalListCollisions

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a global handler function to return the current list of collisions.

It can be used by multiple datasets, but is only used if there is no handler assigned to the dataset using the listCollisions API.

10.20.1. Usage

$fh.sync.globalListCollisions(function listCollisionsHandler(dataset_id, meta_data, cb){});

10.20.2. Parameters

10.20.2.1. listCollisionsHandler

  • Description: The function that is invoked when listing collisions.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.20.3. Example

// This would usually be used by an administration console where a user is
// manually reviewing & resolving collisions.
$fh.sync.globalListCollisions(function(dataset_id, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // sample back-end storage call
  var collisions = getCollisions(dataset_id);
  /* sample response:
  {
    "collision_hash_1" : {
      "uid": "<uid_of_data_row>",
      "timestamp": "<timestamp_value_passed_to_handleCollision_fn>",
      "pre": "<pre_data_record_passed_to_handleCollision_fn>",
      "post": "<post_data_record_passed_to_handleCollision_fn>"
    },
    "collision_hash_2" : {
      "uid": "<uid_of_data_row>",
      "timestamp": "<timestamp_value_passed_to_handleCollision_fn>",
      "pre": "<pre_data_record_passed_to_handleCollision_fn>",
      "post": "<post_data_record_passed_to_handleCollision_fn>"
    },
    "collision_hash_2" : {
      "uid": "<uid_of_data_row>",
      "timestamp": "<timestamp_value_passed_to_handleCollision_fn>",
      "pre": "<pre_data_record_passed_to_handleCollision_fn>",
      "post": "<post_data_record_passed_to_handleCollision_fn>"
    }
  }
  */

  // The callback into the sync service to return the list of known collisions
  return cb(null, collisions);
});

10.20.4. $fh.sync.globalListCollisions for fh-mbaas-api Version Less than 7.0.0

$fh.sync.globalListCollisions(callback)

Similar to $fh.sync.listCollisions, but set the handler globally which means the same handler function can be used by multiple datasets. The global handler will only be used if there is no handler assigned to the dataset via $fh.sync.listCollisions.

10.20.4.1. Example

$fh.sync.globalListCollisions(function(dataset_id, cb, meta_data){

});

10.21. $fh.sync.removeCollision

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a handler function to delete a collision for a Dataset.

10.21.1. Usage

$fh.sync.removeCollision(dataset_id, function removeCollisionHandler(dataset_id, collision_hash, meta_data, cb){});

10.21.2. Parameters

10.21.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.21.2.2. removeCollisionHandler

  • Description: The function that is invoked when deleting a collisions.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • collision_hash

      • Description: the unique hash of the collision
      • Type: String
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.21.3. Example

// This would usually be used by an administration console where a user is
// manually reviewing & resolving collisions.
$fh.sync.removeCollision("todo", function(dataset_id, collision_hash, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // sample back-end storage call
  removeCollision(collision_hash);

  // The callback into the sync service to return the delete row of data
  return cb(null);
});

10.21.4. $fh.sync.removeCollision for fh-mbaas-api Version Less than 7.0.0

$fh.sync.removeCollision(dataset_id, callback)

Defines a handler function for deleting a collision from the collisions list. Should be called after the dataset is initialised.

10.21.4.1. Example

// This would usually be used by an administration console where a user is
// manually reviewing & resolving collisions.
$fh.sync.removeCollision(dataset_id, function(dataset_id, collision_hash, cb, meta_data) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // sample back-end storage call
  removeCollision(collision_hash);

  // The callback into the sync service to return the delete row of data
  return cb(null);
});

10.22. $fh.sync.globalRemoveCollision

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Defines a global handler function to delete a collision.

It can be used by multiple datasets, but is only used if there is no handler assigned to the dataset using the removeCollision API.

10.22.1. Usage

$fh.sync.globalRemoveCollision(function removeCollisionHandler(dataset_id, collision_hash, meta_data, cb){});

10.22.2. Parameters

10.22.2.1. removeCollisionHandler

  • Description: The function that is invoked when deleting a collision.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • collision_hash

      • Description: the unique hash of the collision
      • Type: String
    • meta_data

      • Description: the meta data associated with the data, can be null.
      • Type: Object
    • cb

      • Description: the callback function
      • Type: Function

10.22.3. Example

// This would usually be used by an administration console where a user is
// manually reviewing & resolving collisions.
$fh.sync.globalRemoveCollision(function(dataset_id, collision_hash, meta_data, cb) {
  // The dataset identifier that this function was defined for
  console.log(dataset_id);

  // sample back-end storage call
  removeCollision(collision_hash);

  // The callback into the sync service to return the delete row of data
  return cb(null);
});

10.22.4. $fh.sync.globalRemoveCollision for fh-mbaas-api Version Less than 7.0.0

$fh.sync.globalRemoveCollision(callback)

Similar to $fh.sync.removeCollision, but set the handler globally which means the same handler function can be used by multiple datasets. The global handler will only be used if there is no handler assigned to the dataset via $fh.sync.removeCollision.

10.22.4.1. Example

$fh.sync.globalRemoveCollision(function(dataset_id, collision_hash, cb, meta_data){

});

10.23. $fh.sync.interceptRequest

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Intercept the sync requests for a specific Dataset before it is processed. Use this API to check client identities and validating authentication.

10.23.1. Usage

$fh.sync.interceptRequest(dataset_id, function requestInterceptor(dataset_id, interceptorParams, cb){});

10.23.2. Parameters

10.23.2.1. dataset_id

  • Description: the id of the Dataset
  • Type: String

10.23.2.2. requestInterceptor

  • Description: The function that is invoked when a sync request is received from clients.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the Dataset
      • Type: String
    • interceptorParams

      • Description: the parameters associated with the request
      • Type: Object
      • Supported Keys

        • query_params

          • Description: the query parameters associated with the request
          • Type: Object
        • meta_data

          • Description: the meta data associated with the request
          • Type: Object
    • cb

      • Description: the callback function.

        If it is invoked with a non-null response, the sync request is rejected.

      • Type: Function

10.23.3. Example

$fh.sync.interceptRequest("todo", function(dataset_id, interceptorParams, cb){

  var query_params = interceptorParams.query_params; //the query_params specified in the client $fh.sync.manage
  var meta_data = interceptorParams.meta_data;  //the meta_data specified in the client $fh.sync.manage

  var validUser = function(qp, meta){
    //implement user authentication and return true or false
  };

  if(validUser(query_params, meta_data)){
    return cb(null);
  } else {
     // Return a non null response to cause the sync request to fail.
    return cb({error: 'invalid user'});
  }
});

10.23.4. $fh.sync.interceptRequest for fh-mbaas-api Version Less than 7.0.0

$fh.sync.interceptRequest(dataset_id, callback);

Intercept the sync requests for the specified dataset. Can be useful for checking client identities and validating authentication.

10.23.4.1. Example

$fh.sync.interceptRequest(dataset_id, function(dataset_id, interceptorParams, cb){

  var query_params = interceptorParams.query_params; //the query_params specified in the client $fh.sync.manage
  var meta_data = interceptorParams.meta_data;  //the meta_data specified in the client $fh.sync.manage

  var validUser = function(qp, meta){
    //implement user authentication and return true or false
  };

  if(validUser(query_params, meta_data)){
    return cb(null);
  } else {
     // Return a non null response to cause the sync request to fail.
    return cb({error: 'invalid user'});
  }
});

10.24. $fh.sync.setRecordHashFn

Define a function that will generate the hash value of a single record. A record hash is used when comparing a cached record with the latest from the Dataset Backend.

If the hash matches, the records are assumed to be the same (so no need to update the cache or clients). The default implementation takes a conservative approach by doing a sorted stringification of the record, and calculates a sha-1 of it.

However, you may want to override this to save on CPU time.

IMPORTANT Avoid using fields that are updated server-side in your hash calculation. For example, if a Dataset has a lastModified field that is updated at save time on the Dataset Backend, this should be omitted from the hash calculation. Otherwise, a collision is likely to happen with any subsequent update as clients will be unaware of the new value for that field until the data has synced back with the clients.

This function will allow you to override the default implementation.

10.24.1. Usage

$fh.sync.setRecordHashFn(dataset_id, function generateHash(dataset_id, record){});

10.24.2. Parameters

10.24.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.24.2.2. generateHash

  • Description: The function that will be used to generate the hash of a dataset.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • record

      • Description: the record
      • Type: Object

10.24.3. Returns

The hash value of the record.

10.24.4. Example

$fh.sync.setRecordHashFn("todo", function(dataset_id, record){
  return record.lastModified;
});

10.25. $fh.sync.setGlobalHashFn

Define a function that will calculate the global hash of a dataset. The global hash will be used to determine if a dataset has changed or not.

IMPORTANT Avoid using fields that are updated server-side in your hash calculation. For example, if a Dataset has a lastModified field that is updated at save time on the Dataset Backend, this should be omitted from the hash calculation. Otherwise, a collision is likely to happen with any subsequent update as clients will be unaware of the new value for that field until the data has synced back with the clients.

10.25.1. Usage

$fh.sync.setGlobalHashFn(dataset_id, function generateHash(dataRecordHashes){});

10.25.2. Parameters

10.25.2.1. dataset_id

  • Description: the id of the dataset
  • Type: String

10.25.2.2. generateHash

  • Description: The function that will be used to generate the hash of a dataset.
  • Type: Function
  • Invoked Parameters:

    • dataRecordHashes

      • Description: an array of all the hashes of all the records in the dataset.
      • Type: Array

10.25.3. Returns

The global hash value of the dataset.

10.25.4. Example

$fh.sync.setGlobalHashFn("todo", function(dataRecordHashes){
  return dataRecordHashes.join('');
});

10.26. $fh.sync.globalInterceptRequest

NOTE: RHMAP 3.19 includes fh-mbaas-api version 7. If the version of fh-mbaas-api in your package.json file is less than 7.0.0, see the section for the old version

Intercept all sync requests before they are processed. Use this API to check client identities and validating authentication.

It can be used by multiple datasets, but is only used if there is no handler assigned to the dataset using the interceptRequest API.

10.26.1. Usage

$fh.sync.globalInterceptRequest(function requestInterceptor(dataset_id, interceptorParams, cb){});

10.26.2. Parameters

10.26.2.1. requestInterceptor

  • Description: The function that is invoked when a sync request is received from clients.
  • Type: Function
  • Invoked Parameters:

    • dataset_id

      • Description: the id of the dataset
      • Type: String
    • interceptorParams

      • Description: the parameters associated with the request
      • Type: Object
      • Supported Keys

        • query_params

          • Description: the query parameters associated with the request
          • Type: Object
        • meta_data

          • Description: the meta data associated with the request
          • Type: Object
    • cb

      • Description: the callback function.

        If it is invoked with a non-null response, the sync request is rejected.

      • Type: Function

10.26.3. Example

$fh.sync.globalInterceptRequest(function(dataset_id, interceptorParams, cb){

  var query_params = interceptorParams.query_params; //the query_params specified in the client $fh.sync.manage
  var meta_data = interceptorParams.meta_data;  //the meta_data specified in the client $fh.sync.manage

  var validUser = function(qp, meta){
    //implement user authentication and return true or false
  };

  if(validUser(query_params, meta_data)){
    return cb(null);
  } else {
     // Return a non null response to cause the sync request to fail.
    return cb({error: 'invalid user'});
  }
});

10.26.4. $fh.sync.globalInterceptRequest for fh-mbaas-api Version Less than 7.0.0

$fh.sync.globalInterceptRequest(callback)

Similar to $fh.sync.interceptRequest, but set the handler globally which means the same handler function can be used by multiple datasets. The global handler will only be used if there is no handler assigned to the dataset via $fh.sync.interceptRequest.

10.26.4.1. Example

$fh.sync.globalInterceptRequest(function(dataset_id, interceptorParams, cb){

});

10.27. $fh.sync.getEventEmitter

Get the event emitter of the sync server.

If using sync from fh-mbaas-api, it will return the same emitter instance as $fh.events.

10.27.1. Usage

var emitter = $fh.sync.getEventEmitter();

10.27.2. Parameters

None.

10.27.3. Example

var emitter = $fh.sync.getEventEmitter();
emitter.once('sync:ready', function(){
  //do something here
});

Legal Notice

Copyright © 2018 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat Software Collections is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.