Strategy for sync after a new user registers

Hi. I have a trigger on my atlas database that creates a few documents in a few collections when a new user registers. These collections are to be synced to the new user because they define the layouts of certain screens in a MAUI app.
I found that the first screen would not have received that data when I do my first realm.all for these collections. This is hardly a surprise because the request for all docs is done as soon as I go to the first screen after registering and logging in, so I assume it is before the database has had time to populate the collections. To get over this, I have a simple loop with a 500ms delay in it that attempts to get the data 20 times. This works quite well but I’m not sure if it is a good strategy.
I then stumbled across something in the React SDK usage examples that talks about syncing in the background by making use of

const OpenRealmBehaviorConfiguration = {
type: “openImmediately”,
};

which is used in the Realm.open configuration. I then looked for this in the .net SDK but there is no mention of it. I tried to use it in my .Net MAUI app but it does not know about OpenRealmBehaviorConfiguration

I have a few questions.
Is it correct that this is not available in .Net and will it be available soon?
If I can’t use that, is there another way in .Net to achieve the same so I don’t need to perform a realm.all
If none of that is available, is my loop a good workaround or have I missed the proper way to solve this problem?

I also have an unrelated question. Currently I have 1 realm per model (collection). Is that correct or should I have 1 realm for all my models / collections? That is a pretty basic question so I think I need to do some more reading!

John.

Hi @John_Atkins, thanks for your questions :slight_smile:

So… there is no OpenRealmBehaviourConfiguration in the .NET SDK, but you will get the same effect if you use await GetInstanceAsync(config) instead of GetInstance when retrieving the realm.
Also, if you already opened the realm you can use await realm.SyncSession.WaitForDownloadAsync() to get the latest values locally. Please note that if you’re doing this too soon it could still be that the server didn’t have time to correctly process the documents you just added with the trigger.

Regarding the other question, usually it’s an overkill to have one realm per model. How many realms you need and what models you want to sync in each of them really depends on the structure of your data, of the application and how you want to manage all of it. That said, you can also just have one realm for all your models if that works for you.

I hope this helps :wink:

1 Like

Hi Ferdinando. Thank you for a very useful reply. The more I learn, the more I realise I don’t know!

I was already using realm = await Realm.GetInstanceAsync(syncConfig); and have added

await realm.SyncSession.WaitForDownloadAsync();

but that returns immediately. Presumably, it s too soon for the trigger and function to have started to create collections. This means I need to stick with my loop or find an alternative. I have 5 small docs in the collection in Atlas, and on one occasion, I had only received 2 docs, so my loop exited before the other 3 had been received. I tried dropping my delay from 500ms to 100 ms expecting to receive part of the collection much more often, but weirdly, I keep receiving all 5 now. I expect this is always a possibility.

However, I noticed something else, which almost certainly means I need to change my strategy. After receiving the 5 docs and showing them in my UI, I then added a new doc in Atlas and expected to see it be added to the UI automatically. The reason I expected that was because if I change a doc in Atlas, the UI does update to show that in my app. I expect this is because the realm contains records that I update but does not contain docs that I add in Atlas. I did expect sync to cope with that.

Can you please confirm that to handle adding docs in Atlas (or on another device), I need to subscribe to changes using a realm change listener and when that event fires, I need to do a realm.All?

After your previous reply, I think I understand more about realms (I’ve done some more reading as well). It looks like for various small collections, it would be simpler for me to have 1 realm for them.

I tried “subscribe to changes using a realm change listener and when that event fires, I need to do a realm.All”

but that event never fires. Possibly because it is for changes to the local DB and not for syncing of Inserted records in Atlas database.

Is there a way the app can be informed that records have been inserted in the Atlas database so I can get them with realm.all?

Can you show a piece of code where you do “subscribe to changes using a realm change listener and when that event fires, I need to do a realm.All”? I am a little unsure of what you are doing here.
If you have your code in a public repository you can also just drop a link and I can take a look if you prefer.

The realm listener should fire independently from the origin of the new objects/documents. If the objects have been added locally or in Atlas the listener should fire anyways. It could be that the objects that you’re adding to Atlas don’t follow the schema you’ve defined, and so they do not get synced back to the application or maybe they are not in the set of the results for the subscription queries you’ve defined (I suppose you are using flexible sync, am I correct?).

1 Like

As an additional note, it’ll be useful if you show how you are populating the UI. I’ve seen that you’re using MAUI in another thread, so you should be able to use realm collections with your bindings directly, without the need to use realm listeners directly.

I’m using partition sync at present because I had too many problems trying to get flexible to work. I think partition is all I need for this app but I may change to flexible once I’ve learnt more about it.

I can’t upload this to a public repository because it is for the company I work for. I may be able to make a simple app that shows the same problem.

I don’t want to get into subscribing tp events unless I really need to. I thought I read that is only necessary for background threads. This is simple UI updating that I’m hoping normal sync looks after. If I really need to subscribe to events, then I’ll create a cut-down app that you can look at.

The object added in Atlas definitely follows the schema because all I did was clone a document and change a few fields in it. When I force a realm.all in the MAUI app, then I do receive the new record. The only query I have defined is a realm.all so it should receive any inserted records at Atlas. The UI definitely updates automatically if I change fields in a doc in Atlas.

I am making use of MAUI data binding and that is working perfectly for updates. I’ll tidy up some code and paste some snippets here soon.

You seem to have confirmed that insertions at Atlas should automatically be added to the MAUI UI, so that is good to know. When you say

“maybe they are not in the set of the results for the queries you’ve defined”

perhaps I have not defined the query properly such that Realm knows about it? This is all I have done

Reminders = new ObservableCollection(realm.All().OrderBy(r => r.IndexNo).ToList());

where Reminders is the collection that is bound to my UI. Is that sufficient for Realm to know to monitor the query? As I said, it definitely works for updates.

With “maybe they are not in the set of the results for the queries you’ve defined” I meant the subscription queries, the ones you define if you use flexible sync. I’ve corrected the text in my previous post to make it clearer, but you can disregard it in your case as you’re using partition sync.

Regarding the UI not updating… I can see what’s the problem here. You are wrapping the realm collection in an ObservableCollection, but this way the realm collection doesn’t fire all the notifications that the UI binding framework uses to update the UI.
You should simply do: Reminders = realm.All<>().OrderBy(....). Realm collections are live and implement INotifyCollectionChanged that is used by MAUI to update the UI accordingly. As a general rule you should always try to use Realm collections “as they are”, without wrapping them in other things, as you could lose some of the advantages of live collections. That’s also the reason why you should also avoid using ToList(), as the collections that you obtain is not live anymore.
As an additional note, the reason why updates to single fields still works is that even though your collection is not live anymore, the single objects that are part of the collections are still Realm Objects, and as such they are still live and implement INotifyPropertyChanged and so the UI can change when their content changes.

I’ve seen that in another thread my colleague already recommended an article that I wrote about How to Use Realm Effectively in a Xamarin.Forms App. Maybe that’s a little bit long for an article, but if you want to see some simple code you can take a look at the example we have in our repo, QuickJournal. Here you can see how we define Entries and how we just bind to it in the UI here.

Sorry for the wall of text but I hope this clarifies some things.

1 Like

Don’t be sorry for the length of text! It sounds like you’ve almost certainly solved the problems so I’ll make the changes. The article you wrote is open in another browser tab, along with about 100 other tabs about MongoDB I have open :slight_smile:

Thank you for such a good answer. I’ll make the changes and read your article.

2 Likes

Perfect answer, and I’ve learnt a lot. I’ll definitely read your article and apologise for not reading it before.
Thank you
John.

2 Likes

This also explains and fixes the other problems I was having. I no longer need to loop around waiting for the first sync of the data being created in Atlas due to a trigger.

Just by defining the query, my UI updates whenever the data arrives, which is excellent and, to be honest, the way I hoped it would work.

2 Likes

I’m glad to hear that! And yes that is the way it should work in the majority of cases, with the realm collections/objects updating the UI “automatically”, without the need to define additional data flows in the application.

2 Likes

I just finished reading your very good article on Xamarin Forms and Realm. Do you know when part 2 will be available? It would be great if it used Flexible sync.

I’m glad you liked the article :slight_smile: Unfortunately I have no timeline on when the new article will be released, but for sure it will use flexible sync.

I understand a longer article can probably explain better how to work with flexible sync, but feel free to open new posts on the forum here if you need additional help.

2 Likes

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