I am extremely new to MongoDB, Realm and Atlas. I have been fighting with getting my IOS app to connect to Realm for about two months and I am completely confused. Every time I think I am about to figure it out I get stuck again. I am sincerely hoping someone can help me better understand the Relationship between Realm and Atlas users.
My issue is that I am getting a permission denied error: Code 206:
What’s the relationship between an Atlas User and a Realm User?
None: Atlas users, in the context of a Realm App, are typically the users that have privileged access to the cluster and/or the databases, as maintainers, admins, etc. On the other hand, each Realm App (and you can have multiple in the same cluster) has its own set of users, that register and sign in via the providers you specify, and are not Atlas users.
How do I make sure the Realm user knows that the Atlas user
They don’t, they live in separate contexts, and typically there’s no reason why they would need to communicate: what would be your use case for them to be aware of each other?
Where do I need to look to start trying to figure out what’s going on?
In the setup that you report: “%%user”: “%%partition”, the partition value the user has permissions to access is supposed to be 60c28192a53c1ae905427d96, but you have a value of _partition=60c28192a53c1ae905427d96 instead, hence the permission fails. You should remove the _partition= bit then.
So in other words I believe that the atlas user would be the developer, and the realm user would be whatever user that developer gave the credentials 2 (the client) in order for them to now become the realm user if I’m not mistaken. It is a possibility that I am mistaken. Thus is my current level of understanding on this.
I believe that the atlas user would be the developer
Correct, even though a better definition will be whoever needs access to Administration and Maintenance tasks on the cluster (that in larger companies may not necessarily be just the Developers)
whatever user that developer gave the credentials 2 (the client)
In general, a Realm user is simply an app’s user, identified or anonymous: for example, with Email/Password Provider a user can sign up once, then log in for later connections, all without any intervention from the developer. If there are more complex scenarios (like, paying users that have different levels of features), there must be some logic somewhere to grant the proper access.
Thanks for the detailed answer. I’m sorry its been a while. Life happened. But, now I am determined to get back to this.
I understand that removing the %%user: %%partition setup would solve my problem. But, doesn’t that eliminate the capability of limiting users to their own partitions? Since there is only one user right now, where did the other partition come from? How do I get rid of it and get the right partitions going?
I understand that removing the %%user: %%partition setup would solve my problem.
No, you misunderstood my answer: %%user: %%partition is perfectly valid, it’s the way that you set the partition value that’s a mismatch.
With that setting, you’re saying: “I only give permission to a user to access a partition that matches the user itself”, thus, if the user has _id set to 60c28192a53c1ae905427d96, the partition value must match that exact string (or ObjectId, depending on your schema).
However, you’re setting the partition value at _partition=60c28192a53c1ae905427d96, i.e. you’re adding a _partition= prefix that doesn’t belong there. In other words, to set a partition value you only need to set the value itself, no prefixes, suffixes or anything additional. There may be cases where these may be useful (when you’ve partition values based on complex keys, for example), but not in your simple case.
So where am I adding the _partition prefix that doesn’t belong there? I thought I understood that that’s what we needed to do to set the partitions.
In your reply, you say:
With that setting, you’re saying: “I only give permission to a user to access a partition that matches the user itself”, thus, if the user has _id set to 60c28192a53c1ae905427d96 , the partition value must match that exact string (or ObjectId , depending on your schema).
Isn’t that what I want to do if I want the user to only be able to access their details?
Can you please share the code snippet where you’re setting the partition value? It could typically be during the creation of the object itself, or right after, before inserting it into the DB.
@IBAction func loginPressed(_ sender: UIButton) {
if let email = emailText.text
, let password = passwordText.text {
print("Log in as user: \(email)")
app.login(credentials: Credentials.emailPassword(email: email, password: password)) { [weak self](result) in
DispatchQueue.main.async {
switch result {
case .failure(let error):
// Auth error: user already exists? Try logging in as that user.
print("Login failed: \(error)")
self!.userMessageText.text = "Login failed: \(error.localizedDescription)"
return
case .success(let user):
print(user.id)
print("Login succeeded!")
// Load again while we open the realm.
// Get a configuration to open the synced realm.
let configuration = user.configuration(partitionValue: "_partition=\(user.id)")
// Open the realm asynchronously so that it downloads the remote copy before
// opening the local copy.
Realm.asyncOpen(configuration: configuration) { (result) in
DispatchQueue.main.async {
print ("attempting dispatch")
switch result {
case .failure(let error):
print(error)
fatalError("Failed to open realm: \(error)")
case .success:
self!.ShowHome()
}
}
}
}
}
}
}
}