Get Started with Syncing Data in C++
This guide shows how to use ObjectBox Sync in a C++ app (get the sync library, mark entities for sync, connect to a server).
1) Get ObjectBox Sync
To use Sync you must link your app against the objectbox-sync library (instead of objectbox).
We’ll use the officially documented CMake FetchContent setup and then switch the link target to
objectbox-sync.
CMakeLists.txt
cmake_minimum_required(VERSION 3.14) # per docs 3.14+ example <!-- https://cpp.objectbox.io/installation/#objectbox-library -->
project(myapp) # example name <!-- https://cpp.objectbox.io/installation/#objectbox-library -->
set(CMAKE_CXX_STANDARD 11) # C++11 or higher <!-- https://cpp.objectbox.io/installation/#objectbox-library -->
include(FetchContent) # use FetchContent <!-- https://cpp.objectbox.io/installation/#objectbox-library -->
FetchContent_Declare( # declare OBX dependency <!-- https://cpp.objectbox.io/installation/#objectbox-library -->
objectbox
GIT_REPOSITORY https://github.com/objectbox/objectbox-c.git # official repo <!-- https://cpp.objectbox.io/installation/#objectbox-library -->
GIT_TAG v4.1.0 # example tag <!-- https://cpp.objectbox.io/installation/#objectbox-library -->
)
FetchContent_MakeAvailable(objectbox) # fetch headers & libs <!-- https://cpp.objectbox.io/installation/#objectbox-library -->
add_executable(myapp src/main.cpp) # your target <!-- https://cpp.objectbox.io/installation/#objectbox-library -->
# Link against the Sync variant instead of the core library:
target_link_libraries(myapp PRIVATE objectbox-sync) # sync-enabled <!-- https://cpp.objectbox.io/installation/#objectbox-library -->
By linking objectbox-sync, the Sync client API (from objectbox-sync.hpp) is available to your app.
2) Define Your Data Model for Sync
Enable sync per entity by adding an ObjectBox annotation comment to your FlatBuffers schema (.fbs).
Use /// objectbox: sync immediately before the table you want to sync.
schema.fbs
/// objectbox: sync // enable sync for this entity <!-- https://cpp.objectbox.io/entity-annotations/#supported-annotations -->
table Task { // FlatBuffers table = OBX entity <!-- https://cpp.objectbox.io/entity-annotations/ -->
id: ulong (id); // ObjectBox ID annotation <!-- https://cpp.objectbox.io/entity-annotations/#supported-annotations -->
text: string; // regular property <!-- https://cpp.objectbox.io/entity-annotations/ -->
date_created: ulong (date); // timestamp (ms since epoch) <!-- https://cpp.objectbox.io/entity-annotations/#supported-annotations -->
}
Note:
root_typeis a general FlatBuffers concept and not required by ObjectBox; you can omit it here.
After editing the schema, run the ObjectBox Generator again so the .obx.hpp/.obx.cpp and objectbox-model.json are updated with the sync flag.
3) Start the Sync Client
Create your Store, create a SyncClient for it, and start() the client.
main.cpp
#include "objectbox.hpp" // core C++ API <!-- C++ header ref: https://objectbox.io/docfiles/c/current/objectbox_8hpp.html -->
#include "objectbox-sync.hpp" // sync API & classes <!-- Sync header ref: https://objectbox.io/docfiles/c/current/objectbox-sync_8hpp.html -->
#include "schema.obx.hpp" // generated model code <!-- Generator outputs: https://cpp.objectbox.io/generator/ -->
int main() {
// Build Store with the generated model:
obx::Options opt; // Options API <!-- Options class: https://objectbox.io/docfiles/c/current/classobx_1_1Options.html -->
opt.model(create_obx_model()); // set model on Options<!-- Options::model(...): https://objectbox.io/docfiles/c/current/classobx_1_1Options.html -->
obx::Store store(opt); // open Store <!-- Store class: https://objectbox.io/docfiles/c/current/classobx_1_1Store.html -->
// Server URL: use ws:// for unencrypted, wss:// for TLS.
// Using localhost (same machine):
std::string server_url = "ws://127.0.0.1:9999"; // example endpoint <!-- Sync client docs use ws://127.0.0.1:9999: https://sync.objectbox.io/sync-client -->
// If using the Android Emulator, 10.0.2.2 reaches the host machine:
// std::string server_url = "ws://10.0.2.2:9999"; // emulator host map <!-- Mentioned in Sync docs with link to Android docs: https://sync.objectbox.io/sync-client#start-the-sync-client (see "Using Android emulator?" note) -->
// Create the Sync client (keep it in a shared_ptr as advised by the API docs):
std::shared_ptr<obx::SyncClient> syncClient = obx::Sync::client( // builder <!-- C++ minimal example: https://sync.objectbox.io/sync-client#start-the-sync-client -->
store, // Store <!-- Same as above -->
server_url, // URL <!-- Same as above -->
obx::SyncCredentials::none() // creds <!-- Credentials factory methods incl. none(): https://objectbox.io/docfiles/c/current/classobx_1_1SyncCredentials-members.html -->
); // shared_ptr<!-- SyncClient API is in objectbox-sync.hpp: https://objectbox.io/docfiles/c/current/classobx_1_1SyncClient.html -->
// Start background syncing:
syncClient->start(); // non-blocking<!-- start(): background + reconnect behavior described: https://sync.objectbox.io/sync-client -->
// Your normal ObjectBox usage continues, synced entities will propagate:
obx::Box<Task> box(store); // Box API <!-- Box<> class: https://objectbox.io/docfiles/c/current/classobx_1_1Box.html -->
box.put({0, "My first C++ task", 1730716800000}); // put object <!-- Box operations documented in C++ API: https://objectbox.io/docfiles/c/current/classobx_1_1Box.html -->
// Keep the app running while syncing (start() is async). Also, close sync before closing the Store:
// The sync client runs asynchronously, auto-reconnects; always stop/close it before closing Store.
// Guidance covered in Sync docs ("All of this happens asynchronously" + "Always close the client before closing the store."):
// https://sync.objectbox.io/sync-client
std::cout << "Press ENTER to exit.\n";
std::cin.get();
syncClient->stop(); // stop client <!-- stop/close lifecycle on SyncClient: https://objectbox.io/docfiles/c/current/classobx_1_1SyncClient.html -->
return 0;
}
Production note: instead of none(), use real credentials such as sharedSecret(...) or JWT as recommended.
4) Connect to the Sync Server
Run the Sync Server configured with the same model you generated (point it at your objectbox-model.json).
Example (Linux/macOS)
# Bind locally on port 9999 & load your model JSON:
sync-server --bind=ws://127.0.0.1:9999 \ # bind address/port <!-- bind option doc: https://sync.objectbox.io/sync-server/configuration -->
--model=path/to/build/objectbox-model.json \ # model file (JSON) <!-- --model/-m and JSON modelFile: https://sync.objectbox.io/sync-server/configuration -->
--unsecured-no-authentication # dev-only, no auth <!-- dev option documented (not for production): https://sync.objectbox.io/sync-server/configuration -->
You should see log output from the server on startup and when clients connect.
For long-term setups, prefer a JSON config file (
sync-server-config.json) and use proper authentication (JWT recommended).
Next Steps
- Try the Sync Client page for more options (listeners, request update modes, filter variables).
- Use credentials like
SyncCredentials::sharedSecret(...)or JWT tokens for production. - Review entity relations & constraints for sync: only relations between either all-synced or all-non-synced entities.