LogoLogo
What's NewDeveloper CommunitySupportStatus
  • 🚀Get Started
    • What is JourneyApps Platform?
    • Tutorial: Build your First App
      • 1. Introduction
      • 2. Create a new App
      • 3. OXIDE IDE Overview
      • 4. Hello World app
      • 5. The Data Model
      • 6. View Components
      • 7. Queries and Data Sync
      • 8. Simple Navigation
      • 9. View Stack
      • 10. Input Validation
      • 11. View Parameters
      • 12. Data Manipulation
      • 13. Responsive Apps
      • 14. Styling
      • 15. Lists
      • 16. GPS Capturing
      • 17. Relationships
      • 18. Multiple User Roles
      • 19. Deployment and Users
      • 20. Version Control
      • 21. CSV and APIs
      • 22. Conclusion
    • JourneyApps Platform Fundamentals
      • Creating a New App
        • Git-enabled Apps
      • What are Views?
      • What is the Data Model?
      • JourneyApps Syntax Basics
      • Access the Database (DB)
        • Manipulate DB Objects
        • Query DB Objects
      • View Navigation
        • Deep Linking
      • CloudCode Overview
      • OXIDE (Online IDE)
  • 💻Build your App
    • JourneyApps Syntax
      • Syntax Basics
      • Access the DB
      • View Navigation
      • Async & Await
      • TypeScript Apps (Beta)
        • runtime-build package
        • TypeScript App Troubleshooting
      • What's New in V4
        • Updating to the V4 API
    • Configure your Data Model
      • What is the data model?
      • Reference: model
        • field
        • belongs-to
        • has-many
        • index
      • Data Rules
        • Data Buckets
        • Sync Rules - Limit data synced to devices
        • Data ACLs - Limit access to data
        • Real-world example for Data Rules
        • ❔FAQs
        • Migrate to Data Rules
      • App Indexes
      • Webhooks
    • UI Components
      • All UI Components
        • actionSheet
        • Attachments
        • button
        • button-group
        • capture-coordinates
          • marker
          • marker-query
        • capture-file
        • capture-photo
        • capture-signature
        • card
          • accent
          • action
        • columns
          • column
        • component
        • context-menu
          • divider
          • item
        • CSV
        • date-input
        • datetime-input
        • dialog
          • body
        • display-3d-model
          • 📖display-3d-model Guides
            • Guide 1: Initialize and layout a 3D model in a view
            • Guide 2: Control playback position
            • Guide 3: Troubleshooting controls
        • display-coordinates
        • display-file
        • display-image
        • display-photo
        • display-signature
        • heading
        • html
          • HTML Advanced Topics
          • ❔HTML FAQs
          • 📖Guide: HTML & JourneyApps iFrame Client
        • icons
        • info
        • info-table
          • row
        • journey.photos (capture multiple photos)
        • JourneyPrinter (print PDFs)
        • grid
          • cell
          • 📖grid Examples
        • list
          • list-item
            • accent
            • asset
            • pills
              • pill
            • action
        • multiple-choice-checklist
        • navigation (Navigation drawer)
          • general-section
            • item
          • section
            • item
              • item
          • ❔navigation FAQs
        • notification
        • object-dropdown
        • object-list
          • action
        • object-repeat
        • object-table
          • action
          • column
            • action
            • edit-boolean
            • edit-date
            • edit-datetime
            • edit-integer
            • edit-number
            • edit-select
            • edit-text
            • edit-time
            • edit-typeahead
              • action
            • header-action
          • column-group
          • empty-action
          • 📖object-table Guides
            • Actions
            • Cell callouts
            • Column groups
            • Columns
            • Controlled object-table
            • Controls
            • Copy & paste data
            • Edit cells
            • Filters
            • Frozen columns
            • Fullscreen object-table
            • Mode
            • State
            • Styles
        • optionList
        • PhotonSync (transfer data offline)
        • power-bi
          • 📖Guide: PowerBI Embedding
        • scan-barcode
        • shortcut
        • sidebar
        • single-choice-dropdown
        • single-choice-radio
        • template
        • text-input
        • time-input
        • toggle
        • view
      • JS/TS Events
      • Show / Hide UI Components
      • View Templates
      • XML Fields (Attributes)
        • align-content
        • align-controls
        • align-label
        • bind
        • clear-button-visibility
        • control-order
        • disabled
        • error-message
        • icon-position
        • id
        • hide-if
        • modifier-text
        • label
        • label-case
        • label-color
        • on-change
        • on-press
        • placeholder
        • required
        • show-if
    • JS / TS APIs
      • Attachment
      • Bluetooth (Beta)
      • Broadcast
      • component
      • CSV
      • DB
      • HardwareBarcode
      • journey
        • journey.config
        • journey.container
        • journey.device
        • journey.diagnostics
        • journey.dialog
        • journey.files
        • journey.hardware
        • journey.photos
        • journey.runtime
        • journey.sensors
        • journey.viewStack
      • JourneyPrinter
      • KeyboardBarcode
      • LocalDB
      • NFC
      • OnlineDB
      • PhotonSync
      • SerialPort
      • ShortcutManager
      • TCPSocket
      • user
    • Extend your App with Custom Code
      • App packages
        • App packages overview
        • PDF report package
        • TypeScript library & unit tests
        • Manage External Dependencies
      • Custom HTML
    • Style & Customize your App
      • Style & configure UI components
        • Overview
        • Understand extendable themes
        • Use themes on a view
        • Theme specific components on a view
        • Examples
        • Debugging
        • ❔FAQs
      • Change your App Font
      • Custom Branding
        • Custom Container Features
        • Special Requirements for iOS Containers
    • Integrate your App
      • Backend integrations with CloudCode
      • Barcode Scanning
        • Barcode Scanning using Keyboard Emulation
        • Hardware Barcode Scanning
        • scan-barcode
      • Bluetooth Low Energy (BLE)
      • Broadcast API
      • HTTP requests (Fetch API)
      • JourneyApps Print (Android)
      • Maps and navigation
      • NFC
      • Opening external links/apps
      • Serial Port
      • TCP Sockets
    • Design Intuitive Apps
      • UX Guidelines
      • Write Effective Copy
  • 📱App Features
    • RealWear® Voice Control
      • Automatic Voice Commands
        • Automatic Voice Commands - Advanced
      • Manual Voice Commands
    • App, Runtime and Container Updates
    • Batch Operations (App)
    • Call JS/TS Functions from XML
    • Capture GPS Locations
    • Push Notifications
    • Translations
    • XML Format Strings
    • Webhooks (External)
  • 🌐CloudCode
    • CloudCode Overview
    • Trigger a CloudCode Task
      • Trigger CC with a Schedule
      • Trigger CC via a Webhook
      • Trigger CC from an App
      • Trigger CC from Another Task
      • Trigger CC via HTTP
    • Attachments in CloudCode
    • Timezones
    • Advanced CloudCode Topics
      • Access Multiple DBs in CloudCode Tasks
      • Batch API (CloudCode)
      • CloudCode Dependencies
      • Configure HTTPS in CloudCode
      • Deployment environment variables
      • Local CloudCode Development
      • PDF Reports using CloudCode
      • Shared CloudCode Tasks
      • Translations in CloudCode
  • 📥Backend API
    • Introduction
    • API Reference
      • Retrieve All Objects
      • Query Objects
      • Sort Results
      • Limit and Skip
      • Count Objects
      • Create a New Object
      • Retrieve a Single Object
      • Update a Single Object
      • Delete a Single Object
      • Batch Operations (v4 API)
      • Oplog API
      • Retrieve the App Data Model
      • Manage App Users and Sessions
      • Field Representation
      • Error Responses
    • API Limits
    • Update to the V4 API
  • ⚙️Technical
    • Data Synchronization Priority
    • Device Diagnostics
    • JSON1 Query Engine
    • Improve App Performance
    • Security Measures
    • Supported Platforms
      • Web Container
      • Windows Installer
    • Domain Whitelist
  • 🖥️OXIDE
    • Get started with OXIDE
      • OXIDE Overview
      • Components of OXIDE
    • Configure Testing Deployments
    • Edit and Manage Files
      • How to Navigate to a Function
      • Manage External Dependencies
    • Create and Manage App Containers
    • Debugging & Troubleshooting
      • Common Troubleshooting Pointers
      • App Diagnostics Reports
      • Build Logs
    • OXIDE Workspaces
      • OXIDE Trees
  • ❕Deprecated Features
    • Deprecated Features and Components
Powered by GitBook
On this page
  • Data Buckets
  • Examples
  • Sync Rule Reprocessing
  • Developer Notes
  • Guidance around using sync rules
  1. Build your App
  2. Configure your Data Model
  3. Data Rules

Sync Rules - Limit data synced to devices

PreviousData BucketsNextData ACLs - Limit access to data

Last updated 2 years ago

Sync rules give developers the ability to determine programmatically what data should sync to which devices. Sync rules are important in production applications, where devices should only store data that's needed for the app to work for security and performance reasons.

Sync Rules v1 and v2

The below document details sync rules in apps that have enabled.

  • For documentation on sync rules v2 (sync rules without data ACLs), see the legacy docs . Note that there are no syntax or functional updates for sync rules in apps that have data rules enabled.

  • For documentation on the deprecated sync rules v1, go .

Sync rules vs ACLs

Sync rules specify which data syncs to users' devices, whereas ACLs specify users' access to data objects. This document describes sync rules. You can learn more about ACLs .

Sync rule reprocessing

When changes to sync rules are deployed, all data for that deployment needs to be processed again to take the new sync rules into consideration. Please read more information about sync reprocessing .

Data Buckets

Sync rules are defined in terms of data buckets. It is important that you are familiar with these before moving on to the next sections. Read up about them here:

Data is synched to devices according to the data buckets defined in the data rules.

Important: If access is limited with , syncing could be disabled for a bucket.

See and example of this .

Examples

Synchronize all data

During development, it is useful to not have to worry about sync rules, and synchronize everything. This is not recommended for applications in production, unless the app will only ever contain a small number of objects (around 10 000 or less).

data-rules.xml
<data-rules version="3">
    <global-bucket>
        <all-models />
    </global-bucket>
</data-rules>

Synchronize all data for specific users

data-rules.xml
<data-rules version="3">
    <global-bucket via="self[developer == true]">
        <!-- All data for developers -->
        <all-models />
    </global-bucket>
    
    <bucket via="self[developer == false]/region">
        <!-- Region-specific data for other users -->
        <has-many name="clients" />
    <bucket>
</data-rules>

Synchronize only a subset of data within a model

data-rules.xml
<data-rules version="3">
    <global-bucket>
        <!-- Sync only non-archived category objects -->
        <model name="category" condition="archived != true" />
    </global-bucket>
</data-rules>

Synchronize data for certain users only

data-rules.xml
<data-rules version="3">
    <!-- 'via' specifies how we get from the user to the region -->
    <bucket via="self/region">
        <!-- Sync all clients in the region according to the has-many relationship -->
        <has-many name="clients" />
    </bucket>
</data-rules>

Disable synchronization with the read="online" ACL

data-rules.xml
<data-rules version="3">
    <!-- Neither the region nor its clients are synced -->
    <bucket via="self/region" read="online">
        <has-many name="clients" />
    </bucket>
</data-rules>

Advanced Example

This example combines many of the available configuration options to showcase more complex sync rules:

schema.xml
<?xml version="1.0" encoding="UTF-8"?>
<data-model>
    <model name="user" label="User">
        <field name="name" label="Name" type="text:name"/>
        <field name="role" label="Role" type="single-choice">
            <option key="admin">Admin</option>
            <option key="field_engineer">Field Engineer</option>
        </field>

        <belongs-to model="site" />
        <has-many model="message" inverse-of="sent_by" name="sent_messages" />
        <has-many model="message" inverse-of="received_by" name="received_messages" />

        <display>{name}</display>
    </model>

    <model name="site" label="Site">
        <field name="archived" label="Archived?" type="boolean" />
        <field name="name" label="Name" type="text:name" />

        <has-many model="building" name="buildings" />
        <has-many model="room" name="rooms" />
        <has-many model="equipment" name="equipment" />
        
        <display>{name}</display>
    </model>

    <model name="building" label="Building">
        <field name="archived" label="Archived?" type="boolean" />
        <field name="name" label="Name" type="text:name" />

        <belongs-to model="site" />
        
        <display>{name}</display>
    </model>

    <model name="room" label="Room">
        <field name="archived" label="Archived?" type="boolean" />
        <field name="name" label="Name" type="text:name" />

        <belongs-to model="site" />
        <belongs-to model="building" />
        
        <display>{name}</display>
    </model>

    <model name="category" label="Category">
        <field name="archived" label="Archived?" type="boolean" />
        <field name="name" label="Name" type="text:name" />
        
        <display>{name}</display>
    </model>

    <model name="tool_type" label="Tool Type">
        <field name="archived" label="Archived?" type="boolean" />
        <field name="name" label="Name" type="text:name" />
        
        <display>{name}</display>
    </model>

    <model name="equipment" label="Equipment">
        <field name="archived" label="Archived?" type="boolean" />
        <field name="in_use" label="In Use?" type="boolean" />
        <field name="name" label="Name" type="text:name" />

        <belongs-to model="site" />
        <belongs-to model="room" />
        <belongs-to model="category" />
        <belongs-to model="tool_type" />
        
        <display>{name}</display>
    </model>

    <model name="message" label="Message">
        <field name="archived" label="Archived?" type="boolean" />
        <field name="message" label="Message" type="text" />
        <field name="sent_at" label="Sent At" type="datetime" />
        <field name="received_at" label="Received At" type="datetime" />
        
        <belongs-to model="user" name="sent_by" />
        <belongs-to model="user" name="received_by" />
        <display></display>
    </model>
</data-model>
data_rules.xml
<?xml version="1.0" encoding="UTF-8"?>
<data-rules version="3">
    <!-- Sync the user object itself, required to access 'user' in the app. -->
    <bucket via="self">
        <!-- Also sync all messages that the user has sent or received. -->
        <has-many name="sent_messages" condition="archived != true" />
        <has-many name="received_messages" condition="archived != true" />
    </bucket>
  
    <!-- For non-admin users, sync specific data related to sites. -->
    <bucket via="self[role != 'admin']/site[archived != true]">
        <has-many name="buildings" />
        <has-many name="rooms" />
        <has-many name="equipment" condition="in_use == true" />
    </bucket>
  
    <!-- For admin users, sync data for all sites. -->
    <global-bucket via="self[role == 'admin']">
        <model name="building" />
        <model name="room" />
        <model name="equipment" />
    </global-bucket>
  
    <!-- Some global data is synchronized to all users. -->
    <global-bucket>
        <model name="category" />
        <model name="tool_type" condition="archived != true" />
    </global-bucket>
</data-rules>

Sync Rule Reprocessing

Changes that trigger sync rule reprocessing (when deployed) include:

  • Changes to models, relationships, and conditions in the sync rules.

  • Some (rare) changes in the data model, if it changes the meaning of the sync rules. For example, if the model referenced by a relationship used in sync rules changes, reprocessing will be triggered.

  • White-space changes and comments do not trigger sync rule reprocessing.

During sync rule reprocessing, users can proceed to use their apps as usual, however previous sync rules will apply until reprocessing is complete.

This means that in cases where the new version of the code relies on new sync rules being active immediately, you should plan on deploying your code in multiple phases:

  1. Deploy a change containing only the new sync rules, as well as any new models and fields in the data model.

  2. Once sync rule reprocessing is complete, deploy the rest of the changes.

Sync reprocessing status

The reprocessing status for a deployment (including an estimate of the number of Oplog entries to be processed and the reprocessing duration) can be seen on the "Sync Diagnostics" page in the data browser. You may need to elevate permissions to access this page.

Once sync rules are reprocessing, the status can also be seen in OXIDE's Deployment workspace for the corresponding deployment:

Developer Notes

Here are a few final notes on sync rules for developers:

  • Once sync rules have been deployed for an app, it will become critically important to update the rules when new models are added to the data model, or if model or relationship names change. Failing to do so will result in queries not showing the necessary data in the view, or logic in the JS failing.

  • Sync rules affect what data can be accessed in the app via DB. OnlineDB is unaffected by sync rules.

  • Sync rules constraints have a big impact on data model design. It is often useful to create "sync relationships" which are only used for sync rules, but have no other meaning in the data model.

Guidance around using sync rules

A general rule is to sync only the data that is applicable to a specific app. The fewer data synced, the more performant the app will be in general:

  • Fewer than 10k objects on a device is ideal.

  • Up to 50k objects synced to a device should work but needs to be tested properly. At these data volumes, the app becomes sensitive to poorly-written and unindexed queries. Be sure to monitor the DB size for increases (in the app diagnostics) to prevent unforeseen performance degradations.

It is also possible to synchronize all data only to specific users only, by using the attribute.

Here we specify a to only synchronize a subset of the objects within the category model.

Here we specify the attribute to synchronize all clients in a user's region.

When changes to the sync rules are deployed, all data for that deployment needs to be processed again to take the new sync rules into consideration. The exact processing time varies based on the app and the server load, but it usually takes around 1-2 seconds per 1000 entries in the , or half an hour per million entries.

OXIDE will present a warning dialog when you deploy changes to a deployment that will trigger sync rule reprocessing.

Note: this behavior is different for . Please see for more details.

Up to 500k objects synced to a device can work, but even with performant queries the sync performance will become slow. This will be exacerbated if there are a large number of users syncing the same data or if the data changes often. Strongly consider using aggressive archiving strategies, or .

💻
Oplog
data rules
here
here
here
Data Buckets
data ACLs
below
below
data ACLs
Staging / Production
OnlineDB
this section
via
condition
via