[Realm-Sync] Collection change using two devices sharing the same database

Hi folks!

I am using realm-sync inside my application. The application is cross-platform and targeting IOS and UWP devices. According to the business logic, the same user can log in to two devices simultaneously, sharing the current database. Also, the application uses dot-net reactive extensions to behave reactively when the app objects are created/updated/deleted.
The app has a collection screen (Suppose a list of cars), and there is an item details screen (car details).

Imagine that I have logged in on two devices and have navigated to the item details screen on both devices (let’s say car_1 details). Now I am removing car_1 on the first device. The expected behavior is that I should be navigated back to the cars list screen on the second device (The car_1 has been already deleted).

I have IQueryable<Car> cars as INotifyCollectionChanged object inside the item details view model. And I am listening the cars collection chages using

ObservableForCollectionChanged()
.Subscribe(_ => await NavigateBackAsync());

The problem is that when I delete an item on the first device the collection change event does not emit on the second device.

So the question is, how should I listen to the collection change on second device when it happens on the first one?

It’s hard to say without seeing more of the code. But trying to think about your use case, I don’t believe it can be achieved with collection notifications. You can of course subscribe for notifications on the cars collection (doing that with the regular c# API as I’m not an RX guru, but the concept should be the same):

var cars = realm.All<Car>().AsRealmCollection();
cars.OnCollectionChanged += (s, e) =>
{
    // Here the args will contain the index of the deleted car.
};

The issue is that once the event fires on the second device, you don’t know what the deleted car is - you only have the index. So it’ll be hard to determine whether the user is looking at the deleted car or some other car. A more reliable approach would be to listen for changes on the car itself. Something like:

// In your CarDetailsViewModel
private readonly Car car;

public CarDetailsViewModel(Car car)
{
    this.car = car;
    car.PropertyChanged += this.OnCarPropertyChanged;
}

private void OnCarPropertyChanged(object sender, PropertyChangedEventArgs args)
{
    // The car we're looking at was deleted (IsValid is false) - let's
    // navigate to the previous screen
    if (args.PropertyName == nameof(Car.IsValid) && !this.car.IsValid)
    {
        _ = NavigateBackAsync();
    }
}

That way the car details viewmodel monitors its own car for changes rather than the entire collection. When that car is invalidated due to deleting it from another device, it will detect that and navigate back to the car list.

2 Likes

hi @nirinchev. Thanks a lot for your responce. Sounds really good idea to observe IsValid property change instead of observing a collection change. I will try it.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.