objectbox-dart icon indicating copy to clipboard operation
objectbox-dart copied to clipboard

Impossible to update data on FCM Background Message : object put failed: 10002 ID is higher or equal to internal ID sequence

Open madrojudi opened this issue 3 years ago • 4 comments

Hello, Using objectbox: 1.3.0

I am having a problem trying to update data when I receive a notification from FCM when the application is running in the background. When a notification comes from FCM, the code successfully retrieves the corresponding data from the ObjectBox database. But when the code tries to update this data, it throws an exception Invalid argument(s): object put failed: 10002 ID is higher or equal to internal ID sequence: 31 (vs. 31). Use ID 0 (zero) to insert new entities. Out of 10 attempts 3 fail.

Entity code

@Entity()
@JsonSerializable()
class Requirements implements BaseEntity {

  @Id()
  int localId;
  @Unique()
  String? id;
  String? description;
}

Firebase Messaging Background Handler

WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await _initObjectBox();
Store store = SketchPage.store!;

switch (notification.type) {
   case TypeNotification.REQUIREMENT_RESPONSE:
   case TypeNotification.REQUIREMENT_CANCEL:
     Requirements requirements = await WebService.getNeedsExpressionService()
         .getRequirementsById(notification.objectId!);

     RequirementsDao requirementsDao = RequirementsDao(store);
     bool result = requirementsDao.updateRequirementsStatus(requirements);
     break;
}

Update Requirement Function

bool updateRequirementsStatus(Requirements data) {
    final Box<Requirements> requirementsBox = store.box<Requirements>();
    Query<Requirements> query = requirementsBox.query(Requirements_.id.equals(data.id!)).build();
    Requirements? requirements = query.findFirst();
    if (requirements == null) return false;
    requirements.status = data.status;
    int id = requirementsBox.put(requirements); // fail here
    return id == requirements.localId;
  }

Thank you for helping me.

madrojudi avatar Aug 02 '22 14:08 madrojudi

object put failed: 10002 ID is higher or equal to internal ID sequence

This message indicates that your code is trying to put an object with an ID that has not been assigned, yet. By default, new objects have to be put with ID = 0 (in your case localId) so ObjectBox will assign the next available ID to them. So make sure that it's set to 0, or only to an already assigned ID.

Alternatively, though not recommended, you can change this behavior to let your code assign IDs: https://docs.objectbox.io/advanced/object-ids#self-assigned-object-ids

greenrobot-team avatar Aug 08 '22 07:08 greenrobot-team

@greenrobot-team The error occurs when the application is running in the background and FCM fires. Instead, I'm trying to update an existing data when a notification arrives. When I do a fetch, I retrieve the existing data from the database and when I try to update it, it generates the error. And when it starts and the application receives another notification, it generates an error also related to the ID. But when I restart the application again, it no longer throws an error, even I quit afterwards.

madrojudi avatar Aug 08 '22 19:08 madrojudi

@madrojudi Did you read my comment? If your code wants to update an existing object, it needs to use an existing localId. The error message indicates that your code uses a localId that is not in use by any existing object.

greenrobot-team avatar Aug 09 '22 05:08 greenrobot-team

@greenrobot-team I understood what you said. But it's not me who puts the localId. Looks more like Objectbox doesn't update all the time between differents FlutterEngine. I explain in more detail.

  1. The application runs in the background and receives a notification, this notification indicates that the status of the data, for the id=acedc-125553-fca2233, has changed, it is an example
  2. I run a query to get corresponding data from Objectbox :
{
localId: 31,
id: acedc-125553-fca2233,
status: PENDING,
name: Example
}
  1. Now I just changed the status value, to IN_PROGRESS for example.
localId: 31,
id: acedc-125553-fca2233,
status: IN_PROGRESS,
name: Example
}
  1. I run the query to put the update data, and it generates the error Invalid argument(s): object put failed: 10002 ID is higher or equal to internal ID sequence: 31 (vs. 31). Use ID 0 (zero) to insert new entities.

This is when FCM run on background. It happens, but not all the time. This often happens in the following cases but not all the time :

  1. the user switches to another application without closing my app
  2. the user makes HOME without closing the application
  3. the phone (Android) goes to sleep while the application is in the foreground.

madrojudi avatar Aug 09 '22 06:08 madrojudi

Thanks for the clarification. Maybe this can be solved by using Store.attach to attach to the store that is already open for your app?

See my comment at https://github.com/objectbox/objectbox-dart/issues/436#issuecomment-1168484708 on a similar issue about using multiple Flutter Engines.

greenrobot-team avatar Aug 16 '22 12:08 greenrobot-team

Unfortunately it doesn't always work for me. But I found an alternative that is currently working.

  1. I check if DB is open with Store.isOpen(path). If it is true, I use Store.attach
  2. If Store.isOpen is false, I try to open new Store by openStore. When it open, I save the reference into a file
  3. If Store.isOpen throw error, I check to read the reference which I save in 2. and I use Store.fromReference to open Store

Currently, It is working. I will continue testing to see if it is stable.

madrojudi avatar Aug 18 '22 12:08 madrojudi

Unfortunately it doesn't always work for me. But I found an alternative that is currently working.

  1. I check if DB is open with Store.isOpen(path). If it is true, I use Store.attach
  2. If Store.isOpen is false, I try to open new Store by openStore. When it open, I save the reference into a file
  3. If Store.isOpen throw error, I check to read the reference which I save in 2. and I use Store.fromReference to open Store

Currently, It is working. I will continue testing to see if it is stable.

Hello! This solved my problem.

madrojudi avatar Sep 10 '22 21:09 madrojudi