New async APIs in ObjectBox database 2.0.0 for Flutter/Dart

New async APIs in ObjectBox database 2.0.0 for Flutter/Dart

ObjectBox Flutter database reached 2.0 today – with new async APIs.

This release has major improvements when using ObjectBox with asynchronous programming in Dart. Notably, the Box API has added async variants of methods to get and put one or more objects.

Let’s take the example from the package README and make it async:

The Query API also has added async variants of methods to find matching objects. Let’s make the query example async as well:

Behind the scenes, these use the existing async API provided by Store which runs the operation on a worker isolate. With this release we have made additional improvements that allow it to be used with objects that contain relations (ToOne and ToMany). This made us comfortable to offer it through the new async convenience methods on Box and Query mentioned above.

Sometimes, it is favorable to bundle multiple database operations and execute them “at once”. This is what runInTransactionAsync() is for.  It allows to use the synchronous APIs and wrap them in a single, asynchronous transaction. For example, let’s look at transferring funds between two bank accounts. The fund can safely be transferred from one account to another by reading the current balances, deducting the amount from one account and adding the amount to another account:

This is more efficient than calling multiple async operations and further offers transactional safety as ObjectBox offers ACID semantics.

Ready to go? To upgrade to this major release run flutter pub upgrade objectbox --major-versions (or for Dart Native apps dart pub upgrade objectbox --major-versions ).

To add ObjectBox database to your Flutter project read our Getting Started guide.

As always, we look forward to your feedback on GitHub or via our anonymous feedback form and hope you have a great time building apps with ObjectBox!

How to start using ObjectBox Database in Flutter

How to start using ObjectBox Database in Flutter

This tutorial will help you get started with the ObjectBox Flutter Database. We will create a simple task-list app using all ObjectBox CRUD operations (Create, Read, Update, Delete). Additionally, we will support adding a tag to each task by setting up a to-one relation between tasks and tags. The pure Dart ObjectBox API is very easy to use, as you will see by going through the steps outlined below. 

A couple of useful links:

About the app

Users can enter a new task, choose which tag to apply and add the task. All added tasks are displayed as a checklist with the associated tag. Users can mark a task as finished by ticking its checkbox and delete it by swiping it away. 

Each task entry also shows the date when it was created or finished, depending on the state of the task.

Tasklist example app built with ObjectBox database in Flutter

How to start using the ObjectBox Database in your Flutter app

Add the library

Please refer to the Getting Started page for up-to-date information about adding the ObjectBox dependencies to your project.

Create a model file

ObjectBox is an object-oriented non-relational (NoSQL) database. First, we need to tell the database which entities to store. We can do this by defining a model and then using the build_runner to generate the binding code. The model is defined by writing Dart classes and annotating them.    

Create a model file (e.g. model.dart), where we want to define two entities: one for task tags and one for tasks. These are just Dart classes with the @Entity annotation. Each entity must have an ID property of type int, which serves as the unique identifier. When this is called “id”, the property is recognized automatically but if you want to use a different name, annotate it with “@Id()”. In the Tag class, we also create a String property for the tag name. Here is how the model will look. Don’t worry about the objectbox.g.dart import for now – this file will be generated later.

Additional properties of our Task entity include a String for the task’s text and two DateTime properties for the date when a task was created and finished. Then we also define a to-one relation between Tasks and Tags. This is needed so that one can assign a tag to each task created within the app. We’ll come back to how relations work at the end of this tutorial.

Generate binding code

Once our model is done, we generate the ObjectBox binding code by running flutter pub run build_runner build. This will create the objectbox.g.dart file from the import above. You will need to do this every time you update the model (e.g. by adding or removing an entity or a property), and ObjectBox will take care of the change. However, in cases like entity renaming, you will need to provide ObjectBox with more information. Read more about data model updates in the ObjectBox docs.

Create a Store

Store represents an ObjectBox database and works together with Boxes to allow getting and putting. A Box instance gives you access to objects of a particular type. One would typically create one Store for their app and a number of Boxes that depends on the number of entities they want to store in the database.

In a separate file, e.g. objectbox.dart, we define the ObjectBox class that will help us create the store. We only need a single database store where we get two Boxes – one for each object type. Let’s call these taskBox and tagBox.

So that our app can always display the current list of tasks without the need to actively refresh it, we create a data stream. Within ObjectBox, we can stream data using queries. We query all tasks by using taskBox.query() and order them by date created in a descending order: order(Task_.dateCreated, flags: Order.descending). Then we use the watch() method to create a stream.

Finally, we define the create() method that will create an instance of ObjectBox to use in our app.

Open the store

Now we can initialise the store in our app’s main() function. Do this by calling the create() method of the ObjectBox class.

CRUD operations

CREATE – Put a new Task or Tag into the Store

In the homepage state subclass of main.dart, we define the methods for adding new tasks and tags. Start by creating a task using the input controller. Then, set a tag we want to relate to this task by calling tag.target(). Now we only need to put the new Task object in its Box.

READ – Get all tag names

To get all tag names, we call getAll() on our tagBox. This will return a list with all tags. If you want to read just a single object, call the get(id) method to get only the desired single object back. For a range of objects, use getMany(), passing a list of ids to it.

Another way of reading data is by using queries. In the “Create a Store” section above, we created a task stream with the help of a query builder. There we just needed all tasks, so no criteria was specified. But generally, one can specify custom criteria to obtain a list of objects matching the needs. Learn more about how to use queries using the ObjectBox Query Docs.

 

DELETE – remove tasks by swiping

To remove objects from the database, we add a dismissible Flutter widget. Inside the setState method of the onDismissed property, we simply use the ObjectBox remove() operation with the corresponding task id.

UPDATE – Updating the date when Task was finished 

Our app prints all tasks as a list with checkboxes. Each task’s finished date is initially set to null. We want the finished date of a task to update when the user marks the task as done. The non-null finished date therefore will act as an indicator that the task is finished. Let’s do this inside the setState() method of the onChanged property of our Checkbox class. Set the dateFinished to DateTime.now() if it was null when the checkbox value was changed, and set back to null otherwise. 

Relations

Remember we initialised a ToOne relation in the very first section and planned to come back to this at the end? Now that we have covered all CRUD operations, we can come back to discussing those.

Relations allow us to build references between objects. They have a direction: a source object references a target object. There are three types of relations:

  • to-one relations have one target object, as used above;
  • one-to-many relations can have multiple target objects, but each target only has one source, e.g. we could add a backlink (one-to-many) to Tag in our example to find out all tasks with a specific tag;
  • many-to-many relations involve targets that can have multiple sources, e.g. to improve our example app by supporting multiple tags per task, we could replace the to-one with a many-to-many relation.

Read about relations in more detail and learn how to use them with the help of the ObjectBox Relations Docs or our video tutorial.

How to use relations

When listing all tasks, we might want to include each task’s tag next to the task name. The relations are already initialised (see the “Create a model file” section). Now we need to read the tag of each task we want to list. So, inside the Text widget that displays the task name, we use tasks[index].tag.target?.name to print the name of the corresponding tag.

Build your own Flutter app with the ObjectBox Database

Now you have all the tools needed to build your own version of the task-list app with tags. The setup we described is rather minimal, so that anyone can get started easily. However, this gives you lots of room for improvement. For example, you could replace the existing to-one relation with a to-many, allowing users to add more than one tag per task. Or you can add task-list filtering and/or sorting functionality using different queries. The possibilities are truly endless.

We’d like to learn more about the creative ways to use the ObjectBox Database in Flutter you came up with! Let us know via Twitter or email.

Working student developer relations — part-time, remote, flexible

Please note: We only consider applications that have a cover letter specific to this job offer.

The funded and growing team at ObjectBox is seeking a developer relations talent.

ObjectBox (Techstars ’17) is a company on a mission to bring joy and delight to app developers. The core of our solution is a superfast lightweight, embedded database with easy native language APIs for Java, Kotlin, Swift, Dart (Flutter), Go, and C / C++. On top of the database, we’re building a data synchronisation solution (currently in Early Access).

–> Check out GitHub or the Docs

Job role

There’s quite some flexibility in defining the role and working conditions as well as lots of room to advance within the company depending on your skillset, dreams, and needs. At this moment, we are looking for someone that has a good developer background and a strong passion for developer relations and enjoys making developer products shine. This is a remote part-time position (5-10 hours/week to start with, up to 20 depending on skill set, flexible), ideal for a Computer Science Master student or a freshly graduated Computer Science freelancer.

This is a great position for someone who is looking to gain working experience within the developer market at the intersection of development, community management, and sales.

Main responsibilities

Interact with our users and customers, helping them to use the ObjectBox database and Sync. It entails supporting new customers along the way and providing them with more information when necessary. The associated tasks include:

  • Respond to new inbound leads, helping them to set things up
  • Reply to specific dev-related questions about our products
  • Help maintain our community management channels on GitHub and Stack Overflow
  • Improve our documentation based on user experience

We are looking for someone that is driven and ready to help us take our company to the next level. All of the following tasks are optional, depending on your skill set and ambitions:

  • Developer content creation: tutorials, tech blog articles, videos, etc. – from idea to publishing
  • Developer Marketing: Social Listening Social Media postings (managing the channels), SEO measures, website maintenance (update texts, new content, design)
  • Pitch decks, (web) design, brand positioning
  • Represent ObjectBox at meetups, tech conferences etc (you are expected to submit papers yourself; though we do help of course)

Requirements

  • You are currently pursuing a Masters degree in Computer Science, Information Technology or similar; or have just recently graduated
  • You have an affinity for mobile technologies, IoT, open source, or the digital industry in general
  • You are proficient in at least one programming language (ideally C/C++, Java or Dart) with ideally some application development experience
  • You have a hands-on mentality with strong analytical and communication skills
  • You have very strong English skills
  • You pay attention to detail and enjoy working diligently
  • You are a team-player and fast learner who likes to take over responsibility and appreciates working responsibly

Nice to haves

  • Experience with working in a startup
  • Experience with speaking at tech events (meetups, conferences, etc.)
  • Experience with tech writing
  • Experience with GitHub / open source
  • Experience with Social Media

What’s in it for you

  • The chance to work in one of Europe’s hottest startups (check out our slush pitch)
  • An easy-going and super-friendly working environment in a start-up that is growing, where you will be shaping the company together with us
  • Exciting tasks with the option to learn and grow and take over much more responsibilities as fits your skill set and personal goals
  • Flexibility in every respect: No matter if you just finished your degree or already have a family. We are flexible and looking forward to design the job conditions and contract together with you to match your needs
  • A job in one of the most creative and exciting growing industries: Mobile and IoT

This position is remote, however we’re happy to meet up (occasionally or regularly) if you live in Berlin or Munich.

If this appeals to you, we are looking forward to receiving your application including a possible starting date and salary requirements.

Embedded databases – what is an embedded database? and how to choose one

Embedded databases – what is an embedded database? and how to choose one

What is an Embedded Database?

What is a database?

While – strictly speaking – “database” refers to a (systematic) collection of data, “Database Management System” (or DBMS) refers to the piece of software for storing and managing that data. However, often the term “database” is also used loosely to refer to a DBMS, and you will find most DBMS only use the term database in their name and communication.

What does embedded mean in the realm of databases?

The term “embedded” can be used with two different meanings in the database context. A lot of confusion arises from these terms being used interchangeably. So, let’s first bring clarity into the terminology.

 💡 The term “embedded” in databases

 Embedded database”, meaning a database that is deeply integrated, built into the software instead of coming as a standalone app. The embedded database sits on the application layer and needs no extra server. Also referred to as an “embeddable database”,  “embedded database management system” or “embedded DBMS (Database Management System)”. 

“Database for embedded systems” is a database specifically designed to be used in embedded systems. Embedded systems consist of a hardware / software stack that is deeply integrated, e.g. microcontrollers or mobile devices. A database for such systems must be small and optimized to run on highly restricted hardware (small footprint, efficiency). This can be also called an “embedded system database”. For clarity, we will only use the first term in this article.

Embedded Database vs Embedded System

What is an embedded system / embedded device?

Embedded systems / embedded devices are everywhere nowadays. They are used in most industries, ranging from manufacturing and automotive, to healthcare and consumer electronics. Essentially, an embedded system is a small piece of hardware that has software integrated in it. These are typically highly restricted (CPU, power, memory, …) and connected (Wi-Fi, Bluetooth, ZigBee, …) devices. Embedded Systems very often form a part of a larger system. Each individual embedded system serves a small number of specific functions within the larger system. As a result, embedded systems often form a complex decentralized system.

 

Examples of embedded systems: smartphones, controlling units, micro-controllers, cameras, smart watches, home appliances, ATMs, robots, sensors, medical devices, and many more.

Embedded Database vs Database for Embedded Systems

When and why is there a need for a database for embedded devices?

A large number of embedded systems has limited computational power, so the efficiency and footprint of the DBMS is vital. This fact gave rise to the new market of databases specifically made for embedded systems. Because of being lightweight and highly-performant, embedded databases might work well in embedded systems. However, not all embedded databases are suitable for embedded devices. Features like fast and efficient local data storage and efficient synchronisation with the backend play a huge role in determining which databases work best in embedded systems. 

A database that is both embedded in the application and works well in embedded systems is called an Edge database. To clarify, Edge Database is an embedded database optimised for resource-efficiency on restricted decentralised devices (this typically means embedded devices) with limited resources. Mobile databases, for example, are a type of Edge databases that support mobile operating systems, like Android and iOS.

New Edge databases solve the challenge of an insanely growing number of embedded devices. This applies to both in the professional / industrial as well as the consumer world. Edge databases hence create value for decentralised devices and data by making the former more useful. 

    A database for embedded systems / embedded devices can be simultaneously an embedded database. However, more important is its performance with regards to on-device resource use to serve the restricted devices. A database that is embedded and optimized for restricted devices is called “Edge database”.

    Why use an embedded database in an embedded system?

    First of all, local data storage enabled by embedded databases is a big advantage for embedded systems. Due to the limited connectivity or realtime requirements that these systems often experience, one often cannot rely on it for retrieving data from the cloud. Instead, a smart solution would be to store data locally on the device and sync it with other parts of the system only when needed.

    Aside: a word about data sync. Embedded systems often deal with large amounts of data, while also having an unreliable or non-permanent connection. This can be imposed by the limitations of the system or done deliberately to save battery life. Thus, a suitable synchronisation solution should not only sync data every time there is a connection, but also do it efficiently. For example, differential sync works well: by only sending the changes to the server, it will help to avoid unnecessary energy use and also save network costs.

    The two most important features of databases in embedded systems are performance and reliability. A database used in embedded systems should perform well on devices with limited CPU and memory. This is why embedded databases might work well in embedded systems – they are largely designed to work in exactly such environments. Some of them are truly tiny, which means they thrive in small applications. While better performance helps to eliminate some of the risks, it does not help with sudden power failures. Therefore, a good data recovery procedure is also important. This is most consisely demonstrated by ACID compliance.

    Let’s have a look at the features of embedded databases that make them a great choice for embedded systems. 

    Advantages of embedded databases

    1. High performance. Truly embedded databases benefit from simpler architecture, as they do not require a separate server module. While the client/server architecture might benefit from the ability to install the server on a more powerful computer, this also means more risk. Getting rid of the client/server communication level reduces complexity and therefore boosts performance. 
    2. Reliability. Many embedded devices use battery power, so sudden power failures might happen. Therefore, the data management solution should be built to ensure that data is fully recovered in case of a power failure. This is a popular feature of embedded databases that are built with embedded systems in mind.  
    3. Ease of use and low maintenance. Other important benefits of using an embedded database include easy implementation and low maintenance. Designing embedded devices often requires working in tight schedules, so choosing an out-of-the-box data persistence solution is the best choice for many projects. Since embedded databases are embedded directly in the application, they do not need administration and effectively manage themselves.
    4. Small footprint. Embedded databases do not always have a small footprint, but some of them are smaller than 1 MB, which makes them particularly suitable for mobile and IoT devices with limited memory.
    5. Scalability. As the number of embedded devices grows every year, so does the data volume. An efficient solution should not only perform well with large sets of data, but also adapt to new device features and easily change to fit the needs of a new device. This is where rigid database schemas come as a disadvantage.

     

    How to choose an embedded database

    When choosing an embedded database, look out for such factors as ACID (atomicity, consistency, isolation, durability) compliance, CRUD performance, footprint, and (depending on the device needs) data sync.

    SQLite and SQlite alternatives – a detailed look at the market of embedded databases

    Database solution Primary model Minimum footprint Sync Languages
    SQLite relational <1MB no C/C++, Tcl, Python, Java, Go, Matlab, PHP, and more
    Mongo Realm object-oriented NoSQL database 5 MB+ sync only via Mongo Cloud Swift, Objective-C, Java, Kotlin, C#, JavaScript
    Berkeley DB NoSQL database; key-value store <2MB no C++, C#, Java, Perl, PHP, Python, Ruby, Smalltalk and Tcl
    LMDB key-value store <1MB no C++, Java, Python, Lua, Go, Ruby, Objective-C, JavaScript, C#, Perl, PHP, etc
    RocksDB key-value store   no C++, C, Java, Python, NodeJS, Go, PHP, Rust, and others
    ObjectBox object-oriented NoSQL database <1MB offline, on-premise and cloud Sync, p2p Sync is planned Java, Kotlin, C, C++, Swift, Go, Flutter / Dart, Python
    Couchbase Lite NoSQL DB; document store 1-5 MB sync needs a Couchbase Server Swift, Objective-C, C#, C, Java, Kotlin, JavaScript
    UnQLite NoSQL; document & key-value store ~1.5 MB no C, C++, Python
    extremeDB in-memory relational DB, hybrid persistence <1 MB no C, C#, C++, Java, Lua, Python, Rust

    When to use an Embedded Database and how to choose one

    Firstly, when choosing a database for an embedded system, one has to consider several factors. The most important ones are performance, reliability, maintenance and footprint. On highly restricted devices, even a small difference in one of those parameters might make an impact. While building your own solution with a particular device in mind would certainly work well, tight schedules and additional effort don’t always justify this decision. This is why we recommend choosing one of the ready-made solutions that were built with the specifics of embedded systems in mind. 

    Secondly, to avoid unnecessary network and battery use, you might want to choose an embedded database. On top, an efficient differential data sync solution will help reduce overhead and reduce the environmental footprint.

    Finally, there are several embedded databases that perform well on embedded devices. Each has its own benefits and drawbacks, so it’s up to you to choose the right one for your use case. That being said, we’d like to point out that ObjectBox outperforms all competitors across each CRUD operation. See it for yourself by checking out our open source performance benchmarks.

    Cross platform Data Sync: a simple example

    Cross platform Data Sync: a simple example

    Cross platform data sync can be simple: In this tutorial we will show you how you can easily sync data across devices.

    Built for fast and effortless data access on and across embedded devices from Mobile to IoT, ObjectBox keeps data in sync between devices for you. The Database and Data Snyc works across platforms (iOS, Android, Linux, Rasbian, Windows, MacOS) and supports a variety of languages with easy native APIs (Swift, Java, Kotlin, C / C++, Flutter / Dart, Golang).

    For example, you can sync between an Industrial IoT sensor app in Go and a C++ monitoring application – and a mobile Android app written in Kotlin or Java – and of course an iOS app written in Swift – and… you get the drift 😉

    ObjectBox is a high-performance embedded database for Edge Computing with integrated Data Sync. The ObjectBox database is quick to set up and free and easy to use. Our powerful and intuitive APIs are a great match for multiplatform development environments.

    Syncing data across devices – a task-list app example

    In this tutorial, we are going to sync data across three instances of an example task-list app (written in C++, Go and Java).

    With the task-list app, users can create simple text-based tasks and mark them as done. It stores tasks together with their creation dates. There is also a parameter to store the date when the task was completed. It acts as a filter for users to only see unfinished tasks. 

    This app is a standard cross platform ObjectBox example that is available for all language bindings. Here are the repositories of each example app that we will be looking at today:

    Overview of the example code 

    In this section, we’ll quickly review how the the task-list example app uses ObjectBox Sync. For a more detailed description, check out the Sync docs. If you want to see how each of these steps were incorporated into the example code, go to the next section.

    Note: The basic use of the database and its sync features is the same for all programming languages. If you haven’t used the ObjectBox DB yet, please refer to the corresponding documentation: C/C++ Docs, Java/Kotlin/Dart Docs, Go Docs, Swift Docs.

    For sync to work in any app, we generally only need four things:

    1. The sync-enabled library — this is not the same as the general ObjectBox library and has to be downloaded separately.
    2. Database objects enabled for sync — for this we need include the sync annotation in the ObjectBox schema file.
    3. ObjectBox Sync Server — please apply for a free Sync Trial here to get your own copy of the Sync Server (available for Linux and Docker). Note that this will only have to be started once and in this tutorial we’ll show you how to run the server on Linux. If you are using Docker, follow the steps outlined here.
    4. Start a Sync Client in the app — as one can see from the Sync Client docs, creating and starting a sync client is just a matter of a couple of lines of code.

    Important: When syncing between different apps, please make sure that the UIDs in the model JSON file (e.g. objectbox-default.json) are the same everywhere.

      How to run the examples

      Here you’ll find requirements and step-by-step guides for running the task-list example app in each of the three languages.

      C++ example app

      Requirements

      New to C++? Check out our beginner C++ ObjectBox installation tutorial.

      • WSL Ubuntu
      • CMake
      • Git
      • C++
      • Clang

        Step-by-step guide

        1.Start by creating a CMakelists.txt file:

        Now configure and build the project via CMake: Configure (Clang), CMake: Build.

        2. Sync-enabled objects: note the first line in tasklist.fbs.

        3. [if not running a server already] Start the ObjectBox Sync Server on Linux by running ./sync-server --model build/_deps/objectbox-src/examples/cpp-gen/objectbox-model.json --unsecured-no-authentication

        where sync-server is the path to your sync server executable. You can find more information about the server in the Sync Server docs.

        4. Sync Client: launch [objectbox-c-examples-cpp-gen-sync], and the Sync Client will start automatically. You can see how it was implemented in main.cpp.

        As this is just an example, we opted for no authentication to make things simple. This is not what you would use in production. We currently offer two authentication methods: shared secret and Google Sign-In. Here is the relevant Sync docs section on authentication options that explains how to use these.

        5. Let’s add a first task, called “task-cpp” (new task-cpp-1), to check if our C++ app syncs correctly. The output should look like this:

        Output of the C++ tasklist example app, showing a newly added task

        6. You can finally open the Admin UI to check if the task appears there. This is most easily done by opening http://127.0.0.1:9980/ in any web browser. For a more detailed description of what this can do, check out the Admin UI docs.

        Go example app

        Requirements

        • WSL Ubuntu
        • Go (see how to configure it for VS Code here)
        • Git

        Step-by-step guide

        1. First, clone the objectbox-go repository to your VS Code project. Make sure the current directory is objectbox-go.

        2. Sync-enabled objects. There are two versions of the task-list example: with and without sync. To run the one with sync, we need to enable our Task object for syncing. To do this, simply put the sync annotation on a new line in examples/tasks/internal/model/task.go:

        Then run the generator: go generate examples/tasks/internal/model/task.go to update the schema.

        3. [if not running a server already] Now start the ObjectBox Sync Server: ./sync-server --model=examples/tasks/internal/model/objectbox-model.json --unsecured-no-authentication,

        where sync-server is the path to your sync server file. You can find more information about the server in the Sync Server docs.

        4. Run go run examples/tasks/main.go. The Sync Client will start within the app; check main.go to see how this was implemented.

        As this is just an example, we opted for no authentication to make things simple. This is not what you would use in production. We currently offer two authentication methods: shared secret and Google Sign-In. Here is the relevant Sync docs section on authentication options that explains how to use these.

        5. Now we can add our first task (new task-go) – if it synced correctly, you should already see that from the output of the app. In particular, there will be a message from the change listener (“received 1 changes”):

        Output of the Go task-list example app after adding a first task

        6. Lastly, open the Admin UI to check if the task appears there. This is most easily done by opening http://127.0.0.1:9980/ in any web browser. For a more detailed description of what this can do, check out the Admin UI docs.

        Admin UI showing a task created with the Go example app

        Java (Android) example app

        Requirements

        • Java
        • Android Studio

        Step-by-step guide

          1. First of all, open Android Studio and clone the objectbox-examples repository via File → New → Project from Version Control. Use this URL: https://github.com/objectbox/objectbox-examples.git
          2. Sync-enabled objects: check out Task.java to see how this was done (note the @Sync annotation).
          3. [if not running a server already] Start the ObjectBox Sync Server

        ./sync-server --model android-app-sync/objectbox-models/default.json --unsecured-no-authentication,

        where sync-server is the path to your sync server file. You can find more information about the server in the Sync Server docs.

        1. Now you can run “android-app-sync” on a device of your choice. The Sync Client will start in the app. 

        As this is just an example, we opted for no authentication to make things simple. This is not what you would use in production. We currently offer two authentication methods: shared secret and Google Sign-In (only for Java, Kotlin, Dart, C & Go). Here is the relevant Sync docs section on authentication options that explains how to use these.

        5. Add a new task called “task-java”.

        6. Finally, open the Admin UI to check if the task appears there. This is most easily done by opening http://127.0.0.1:9980/ in any web browser. For a more detailed description of what this can do, check out the Admin UI docs.

        Next Steps

        How easy was that? cool Now that you’ve run your first ObjectBox Sync example, why not build something yourself? Use any combination of the supported languages to build your own cross platform app.

        We’re eager to see your use case examples! Don’t hesitate to share your results with us by posting on Social Media and tagging @objectbox_io, or simply sending us an email on contact[at]objectbox.io. 

         

        If you want to learn more about how ObjectBox can be used in IoT, here is an overview of different use cases