Enable Dark Mode!
By: Nihala MK

How to Integrate Flutter Application with Odoo Backend

Technical Flutter

Dart Odoo RPC Client Library

Developers can use the Odoorpc library to integrate their Flutter applications with an Odoo backend. This enables them to leverage the capabilities of Odoo, such as managing sales, invoices, products, and more, within their mobile application.
* Initialize the client using a stored Odoo session.
* Use the database name, username, and password to authenticate.
* Send controllers for JSON JSON-RPC queries.
* Use CallKw to run public methods.
* Get stream updates for Odoo sessions.
* Terminate session (logout)..
* When a session expires, catch exceptions.
How To Install
Execute this command:
Using Dart:

dart pub add odoo_rpc

Using Flutter:

flutter pub add odoo_rpc

This will execute an implicit dart pub get and add the following line to your package's pubspec.yaml file:

  odoo_rpc: ^0.5.2

As an alternative, your editor might be in favor of flutter pub get or dart pub gets. To find out more, check the editor's documentation.

Import it.

Now, you may use: in your Dart code.

import 'package:odoo_rpc/odoo_rpc.dart';


Once connected, you can use odoorpc to perform various operations on the Odoo database.

Basic RPC call

This script connects to an Odoo server, authenticates with it, and retrieves information about installed modules. It demonstrates basic error handling and how to make an RPC call using the odoo_rpc package in Dart.

import 'dart:io';
import 'package:odoo_rpc/odoo_rpc.dart'
main() async {
  final client = OdooClient('https://my-db.odoo.com');
  try {
    await client.authenticate(‘database’, ‘username’, ‘password’);
    final res = await client.callRPC('/web/session/modules', 'call', {});
    print('Installed modules: \n' + res.toString());
  } on OdooException catch (e) {

Example of Flutter using FutureBuilder.

import 'package:flutter/material.dart';
import '../main.dart';
class HomePage extends StatefulWidget {
 const HomePage({super.key});
 State<HomePage> createState() => _HomePageState();
class _HomePageState extends State<HomePage> {
 void initState() {
 Future<dynamic> fetchSales() {
   return orpc.callKw({
     'model': 'sale.order',
     'method': 'search_read',
     'args': [],
     'kwargs': {
       'context': {'bin_size': true},
       'domain': [],
       'fields': [],
       // 'limit': 80,
 Widget buildListItem(Map<String, dynamic> record) {
   return ListTile(
     // leading: CircleAvatar(backgroundImage: NetworkImage(avatarUrl)),
     title: Text(record['name']),
     subtitle: Text(record['partner_id'][1]),
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: Text('Sale Orders'),
     floatingActionButton: Padding(
       padding: const EdgeInsets.all(25.0),
       child: FloatingActionButton(
         onPressed: () {
           Navigator.pushNamed(context, '/sale');
         backgroundColor: Colors.blue,
         child: const Icon(
     body: Center(
       child: FutureBuilder(
           future: fetchSales(),
           builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
             if (snapshot.hasData) {
               return ListView.builder(
                   itemCount: snapshot.data.length,
                   itemBuilder: (context, index) {
                     final record =
                     snapshot.data[index] as Map<String, dynamic>;
                     return buildListItem(record);
             } else {
               if (snapshot.hasError) return Text('Unable to fetch data');
               return CircularProgressIndicator();


The code begins by importing two libraries. The first is flutter/material.dart, which is the core Flutter framework for building applications. The second is main.dart from a parent directory (indicated by ../), which likely contains the entry point of the application.

 import 'package:flutter/material.dart'; 
 import '../main.dart';

HomePage Class:

* This defines a stateful widget named HomePage. Stateful widgets can change their state over time.

* It also overrides the createState method to create an instance of _HomePageState, which is the associated state class.

class HomePage extends StatefulWidget { 
const HomePage({super.key}); 
@override State<HomePage> createState() => _HomePageState();

_HomePageState Class:

* This class is responsible for managing the state of the HomePage.

* It overrides the initState method, which is called when the widget is inserted into the tree. This method can be used for one-time initialization tasks.

class _HomePageState extends State<HomePage> {
 void initState() {

Future<dynamic> fetchSales():

* This function returns a Future that will eventually resolve to a dynamic value. In this case, it's likely an asynchronous operation (like a network request) that will return data from the Odoo server.

* This is an asynchronous method that returns a Future. It seems to make a remote call to an Odoo server to fetch sales orders.

build Method:

* This is where the UI of the widget is constructed. It returns a Scaffold widget, which provides the basic structure for the page.

* The Scaffold contains an AppBar with the title "Sale Orders" and a FloatingActionButton for adding new sale orders.

The argument passed to callKw is a dictionary (or map in Dart). It contains several key-value pairs that configure the RPC call:

* 'model': 'sale.order': Specifies that the RPC call is related to the model 'sale.order' in the Odoo database. This likely refers to the Sale Order model in Odoo, which may contain information about sales transactions.

* 'method': 'search_read': Indicates that the method being called is search_read. This is a common Odoo RPC method used to search for records and retrieve their data.

search_read -This is a common Odoo RPC method used to search for records and retrieve their data.

write - The write method used to update or modify the existing record

create -The write method used to create new records

* 'args': []: This seems to be an empty list, indicating that no additional arguments are being passed to the search_read method.

* 'kwargs': {...}: Contains keyword arguments (kwargs) that further configure the behavior of the RPC call. Here's what each key might mean:

* 'context': {'bin_size': true}: The context is a dictionary that can be used to pass additional information to the server. In this case, it includes the key 'bin_size' set to true. This might be relevant to handling binary data (like images or files).

* 'domain': []: The domain is used to filter the records being searched. An empty list [] might indicate that no specific domain is being applied, meaning it's retrieving all records.

* 'fields': []: This likely specifies the fields to include in the result. An empty list [] might indicate that all fields are included.

* 'limit': 80: This indicates that there's an option to limit the number of records returned, but it's currently disabled.

Error Handling: 

Be sure to implement error handling to deal with scenarios like network issues, authentication failures, or server errors.

Using odoorpc in Flutter allows developers to integrate their mobile applications with Odoo, providing a powerful backend for managing various aspects of business operations. This can include tasks like managing sales, customer relationships, products, and more. By leveraging the capabilities of Odoo, Flutter developers can build robust and feature-rich business applications.

Referred by:https://pub.dev/packages/odoo_rpc

If you need any assistance in odoo, we are online, please chat with us.


Leave a comment




Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635



Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.



Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message