“Operation canceled” Realm Error Domain=io.realm.unknown Code=89

@Jean-Baptiste_Beau You may want to clear the Cache of Realm Studio and see if that resolves the issue. It should be under one of the drop downs of Realm Studio, as I recall, under Help

I tried clearing Cache, doesn’t help. I’ve uninstalled the app on the device countless times too. As @Jay suggested, I checked the logs on Realm studio and saw that I get the following error: {"type":"https://docs.realm.io/server/troubleshoot/errors#access-denied","title":"The path is invalid or current user has no access.","status":403,"code":614} . At least that’s more specific. I tried deleting the realm and recreating one, so now the Realm on the cloud is empty, to avoid schema mismatch as described here. Any idea?

I’m sure the URL is correct because: after deleting the Realm file on Studio, I got this error: {"type":"https://docs.realm.io/server/troubleshoot/errors#access-denied","title":"The path is invalid or current user has no access.","status":403,"detail":"A non-admin user is not allowed to create realms outside their home folder. UserId: '261b6207e5960677d91fec7a75505c46'. RealmPath: '/common'","code":614}. As soon as I recreated the Realm in Studio, this error turned into the one described above.

Okay I can confirm this is a permission problem. In my code, I’ve logged in with some user account, and I’ve got the same error. Then, I made this particular user an administrator in Realm Studio, and I could now load the Realm, read and write data without error! Which leads to my initial question:

You need to give the user permissions

@Ian_Ward well okay, I added that to my JS script that adds objects to the shared realm. I used the code provided by bigFish24 here.
Code looks like this:

async function main() {
  // login
  var adminUser = Realm.Sync.User.current;
  if (adminUser === undefined) {
    let creds = Realm.Sync.Credentials.usernamePassword(adminUsername, adminPassword);
    adminUser = await Realm.Sync.User.login(auth_address, creds);
  }

  // open realm
  const realm = await Realm.open({
    sync: { user: adminUser, url: common_realm_address },
    schema: [MySchema]
  });

  // write data...

  // grant permissions
  const managementRealm = adminUser.openManagementRealm();

  var permObj;
  managementRealm.write(() => {
    permObj = managementRealm.create("PermissionChange", {
      id: "common_all_read",
      createdAt: new Date(),
      updatedAt: new Date(),
      mayManage: false,
      mayWrite: false,
      mayRead: true,
      userId: "*",
      realmUrl: common_realm_address
    });
  });

  // Listen for `PermissionChange` object to be processed
  managementRealm
    .objects("PermissionChange")
    .filtered("id = $0", permObj.id)
    .addListener((objects, changes) => {
      console.log("Permission Status: " + permObj.statusMessage);
    });

  // close realm
  realm.close();
}

And I get the following error:
UnhandledPromiseRejectionWarning: TypeError: adminUser.openManagementRealm is not a function

I guess there’s no way to grant permissions directly in Realm Studio? And that the code I copied is outdated? What would be the correct way now?

@Jean-Baptiste_Beau The way shown in the docs I linked - Full-Sync permissions - Realm Sync (LEGACY)

I think my question here is that while @Ian_Ward is suggesting to set up permissions, with the code you used on your SO post, you were logging in with anonymous auth and got the error.

With our app, whether with auth as an admin user or anonymous auth, we can access the Realm. e.g.

let creds = SyncCredentials.usernamePassword(username: "realm-admin", password: "password", register: false)
            SyncUser.logIn(with: creds

or

let creds = SyncCredentials.anonymous()
            SyncUser.logIn(with: creds

produces the same result

So in your case, if we draw a correlation, you have an admin user ‘realm-admin’ and if you login with that, you should be able to access your data. If you switch the auth to anonymous, you should still be able to access that same data.

That doesn’t really address the question directly as it’s unclear what this means

readable by everyone

Does ‘everyone’ mean other defined users? e.g you have 10 pre-defined users who you want to have read access (so there would be 10 users listed in the Realm Studio Users tab) or does ‘everyone’ mean everyone that uses the app and does not have a user account set up?

@Jay It seems we are in the same situation, but then I don’t see why I can’t access the data while you can. The global Realm you are accessing, how did you create it? In Realm studio, from client, from server code?

By “readable by everyone”, I mean by every logged-in users, whether they come from anonymous login or JWT. My app is made in such a way that users with no account set up are automatically logged in anonymously to access the shared data, as I believe you can’t access the data if you don’t have a SyncUser instance. That question was addressed here.

@Ian_Ward If I use the code on the doc you link:

// grant permissions
adminUser
  .applyPermissions({ userId: "*" }, realmPath, "read")
  .then(permissionChange => {
    console.log("Permission applied successfully.");
  })
  .catch(error => {
    console.log("Error while applying permission: ", error);
  });

Then neither of the two log statements is printed, and I still see “User permissions: This realm has no permissions” on Realm Studio.

During development, we frequently delete and re-create our database from code so we actually do very little from Realm Studio - mostly use it to monitor data changes as we are building relationships between objects. So everything we do is from code.

As a test, I deleted all data associated with a little Tasks macOS app we have. I ran the app with authenticated user ‘Jay’ (see my code above) and added a few tasks. I then logged out. I then logged in as an anonymous user (using the above code) and all of the Tasks Jay created were available and visible to the anonymous user. Created tasks, logged out, logged back in as Jay and the Tasks persisted.

I then checked the Realm from another device using Realm Studio and all of the data from both logins was there (e.g. it sync’d to the cloud correctly).

Here’s what our Realm Studio looks like - very similar to yours.

@Jay well that’s the behavior I’m trying to achieve :sweat_smile: but it doesn’t work for me… What is your realm creation code? I’m assuming Jay is an admin user here, but do you create the realm from the client app or from backend code?

I thought I found the solution but no… I thought the problem could be related to JS/Swift mismatches, so I made the following:

  1. Delete the Realm file on Realm Studio.
  2. Log in from my client app (swift) with an admin user, created the Realm at path /common, added an element to it. I can see the new object in Realm Studio.
  3. Log out on the client app and log in with an anonymous user. Tried to open the Realm.

I got the exact same error. Operation canceled on the client and "The path is invalid or current user has no access.","status":403,"code":614 on Realm Studio logs.

Well, the Realm is instantiated as soon as the user logs in; the Realm objects are are instantiated in the Realm at that time.

Everything is done in the apps code (macOS, Swift).

Sample code with synchronous Realm opening:

    let MY_INSTANCE_ADDRESS = "myinstance.cloud.realm.io"
    let AUTH_URL = URL(string: "https://\(MY_INSTANCE_ADDRESS)")!
    let COMMON_REALM_URL = URL(string: "realms://\(MY_INSTANCE_ADDRESS)/common")!

    let adminCreds = SyncCredentials.usernamePassword(username: "admin", password: "password")
    
    SyncUser.logIn(with: adminCreds, server: AUTH_URL) { (user, error) in
        guard error == nil && user != nil else { return print(error) }
        print("logged in")
    
        let config = SyncUser.current?.configuration(realmURL: COMMON_REALM_URL, fullSynchronization: true)

        let realm = try! Realm(configuration: config!)
        let x = MyObject(id: 2020, name_fr: "test_fr", name_eng: "test_eng")
        try! realm.write { realm.add(x) }
        
        SyncUser.current?.logOut()
        
        SyncUser.logIn(with: SyncCredentials.anonymous(), server: AUTH_URL) { (user, error) in
            guard error == nil && user != nil else { return print(error) }

            let config = SyncUser.current?.configuration(realmURL: COMMON_REALM_URL, fullSynchronization: true)

            let realm = try! Realm(configuration: config!)
            let x = MyObject(id: 2021, name_fr: "test_fr", name_eng: "test_eng")
            try! realm.write { realm.add(x) }
        }
    }

Result: when opening the Realm synchronously, I don’t get the Operation canceled error on the client but I still get the permission error on Realm Studio. I also don’t see any of the two objects in Realm Studio. I see “This Realm has no classes defined”.

But the first time you create the Realm, you must be logged in with an admin user right? Otherwise you get an error that regular users can’t create realms at top-level path, don’t you?

We don’t ‘create the realm’ it ‘creates’ itself. Just like when you add a new Realm object in code - it’s model magically appears in your realm

@Jean-Baptiste_Beau That code looks correct to me - you should open a support ticket. What version of RealmJS are you using?

@Ian_Ward I’m using version 6.0.3 for RealmJS. For RealmSwift, I’m using latest version. I will file a support ticket.

I filed ticket #6493.

Following tech support people’s advice, I will migrate my app to MongoDB Realm, since the legacy infrastructure might be deprecated in a near future.

This question is thus no longer relevant in my situation and is bound to remain unanswered.

Many thanks to @Jay and @Ian_Ward for doing their best to help.