Proper Use of AsyncOpen to open read-only realms


#1

Hi everyone! I’ve been encountering a strange issue with the AsyncOpen method. I’m running ROS on a DO droplet, and I’m using Realm Swift to synchronise data from ROS. I’m opening the current user’s default realm for reading/writing profile data & opening another user’s realm in read-only mode to allow the current user to view the user’s profile data.

When I load the app initially, the data from the read-only realm is downloaded. However, when the other user updates his profile info from another device, or when I manually update the other user’s profile using Realm Studio, the data on the current user’s device from the read-only realm never gets updated unless I relaunch the app.

I’ve tried the following approaches, and I encounter problems with each:

  1. I call the AsyncOpen method again - the callback never gets called
  2. I manually call the read-only realm’s refresh method - it always returns false & the data isn’t updated
  3. I set-up an observer on the realm during the initial AsyncOpen method call - the observer’s notification block never gets called
  4. I set-up an observer on the profile object itself (which I understand isn’t advisable since it’s contained within a read-only realm) - same results as number 3, notification block never gets called

What could I be missing? Any advice would be most welcome.


#2

@filjedi Are you persisting the realm reference for each realm? The realms should sync continually as long as the variable is persisted - it sounds like your reference might be going out of scope and being gc’d. If you turn up the logs on the client and server side anything pop up there?


#3

@ianward Yes, I’m persisting the realm reference for each realm. As for the logs, client logs show that the reference is valid, but in the server logs, I get the following error after each app launch:

“Sync Connection[8653]: Session[1]: Permission denied (message_type=‘upload’, path=’/xxxxxx/userRealm’)” where “xxxxxx” is the other user’s realm identity.

This error only appears once after the app launches (when the AsyncOpen method is called initially, I assume). However, the data downloaded is valid & the same as the data on the server.


#4

@filjedi Looks like you have a permissions issue - take a look here:
https://docs.realm.io/platform/using-synced-realms/access-control/path-level-permissions#reading-permissions

There is a retrievePermissions API that you can use on each user to see what realms they have access to


#5

I called the retrievePermissions method & compared the results with the permissions displayed for the realm on Realm Studio. Both show that the current user has “read” access to the other user’s realm. Could there be another possible cause for the “Permission denied” error?

ADDED: I ran another method (getPrivileges) on the other user’s realm after the initial sync (& after I get the “Permission denied” error from the server logs), and strangely enough, the current user has “read, update, setPermissions, modifySchema” permissions on the other user’s realm.


#6

@filjedi Sounds like you might be mixing up permissions? There is path-level and fine-grain - you can read about the difference here:
https://docs.realm.io/platform/using-synced-realms/access-control


#7

@ianward I’m not sure if that’s the case here. Here’s basically how the app handles permissions:

  1. When user installs & launches the app for the first time, I call the SyncUser.logIn method to login the user
  2. I call a custom method to populate the user’s “profile” object with data
  3. I call the realm’s write method to save that object to the realm
  4. When a user wants to allow another user to view his data, I call the SyncUser createOfferForRealm method to retrieve an access token
  5. The other user gets that token & I call the SyncUser acceptOffer method to accept the offer
  6. I call the asyncOpen method to open the other user’s realm

After subsequent app launches, I just call the asyncOpen method again to open the other user’s realm. After this initial call after app launch, I’m able to retrieve the other user’s data, but the “Permission denied” error immediately appears. Subsequent calls to either asycOpen or refresh fail until the app is relaunched.


#8

@filjedi I see - those methods are old and are set to be deprecated soon. Can you please move to the apply method here:
https://docs.realm.io/platform/using-synced-realms/access-control/path-level-permissions#granting-permissions


#9

@ianward Cool, thanks for the tip, I’ll check out the link you shared. So, does this mean that the “createOfferForRealm” & “acceptOffer” methods are no longer recommended moving forward? If so, is there a non-deprecated method I can use that offers equivalent functionality?


#10

@filjedi We have tests for this in our SDK but few customers use this functionality so our plan was to deprecate this in a major release.

If there is an error in our SDK we should fix that - if you can provide a repro case and open a ticket to support.realm.io - I will get it sorted.

I wanted to present an alternative approach that I know works which is the .applyPermissions api


#11

No problem @ianward, I’ll run some more tests before I open the ticket. In the meantime, I’ll try an alternative approach using the applyPermissions API. Thanks for the help so far :+1:t3:


#12

@ianward To update you, I temporarily implemented a workaround where, after the current user has accepted the offer token from the other user, the other user will manually apply the read permission for the current user the next time the app is launched or refreshed. After this, the data now updates in “real-time” as desired. Thanks again for the assistance :smile: