Delete Realm Database from Realm Cloud

ros

#1

Using Swift, how do you delete/remove a Realm database from Realm Cloud?

Suppose we have a realm with the following structure

My_Realm
  /default
  /ToDo
  /ToDoOld

and /ToDoOld is no longer used and should be deleted. I know this can be done from the Realm Object Server but we want to be able to do it in code within our project. What’s the Swift function?

macOS 10.14, Realm version: 3.11.0


#2

Answering my own question here due to an answer from support.

We don’t have any method in our API that allows deletion of realms programmatically. You can delete realms with https requests by sending a DELETE.


#3

Looks like the link was removed. Is there a github issue or feature request for programmatically deleting a realm from realm cloud? I am not find one which is surprising.


#4

its here
https://docs.realm.io/server/v/3.x/customize/working-with-realms-on-the-server/deleting-realms


#5

@ianward

Thanks for the updated link. I am not sure that fully addresses the question, I may not be looking at the right place though.

The original question was about deleting a database from Realm Cloud.

The linked documentation states one way is to use HTTP DELETE, and then goes on to state via an example

$ wget --method DELETE --header ‘Authorization: MY_ADMIN_TOKEN’ http://127.0.0.1:9080/realms/files/abc%2Fproducts

Which requires an admin token. But upon reviewing the Realm Cloud documentation we find

So… is there another example or more information about how to accomplish this without having access to the Admin Token? Or perhaps the documentation is in need of an update?

Do you per chance have any Swift code to perform this task?


#6

@jay You can obtain a valid token from any Admin User on your instance. You can use the same pattern needed for GraphQL to obtain a valid token as shown here:
https://docs.realm.io/sync/graphql-web-access/how-to-use-the-api#authentication


#7

We finally have a solution. There’s some vagueness in the overall documentation so hopefully this will help others in the future. Big thanks to Realm’s @eric.mossman for working through this to come up with a solution.

To recap, during development (in Swift), there are times when you may want to wipe your database. While that task is pretty well documented and discussed for local Realms, if you’re using a cloud based Realm, it’s requires a different bit of code.

I’ll point you to the current documentation Deleting a Realm with a HTTP DELETE call but as of this writing, it’s not accurate for what is called a ‘Global Realm’ which by definition is

“A global realm is a full sync realm that is not preceded by a syncUser ID. Only admin users can create global realms”

And to clarify, Synchronized Realms come in two flavors: Query-based and Fully synchronized. You can read more about definitions here. The below code works for Full Sync’d realms and may for Query based but I have not tested. I would suggest reviewing the above link about Deleting but don’t spend a lot of time trying to decipher the intricacies as it doesn’t apply in some cases.

One thing to keep in mind is that if you delete your cloud Realm, Realm will know about it and try to push your local data back up to the cloud which would re-create your data. So when deleting, delete locally and then immediately delete the Cloud Realm.

There are a couple of parts to the task; get a ‘token’ for an admin user from Realm, then using that construct a URLSession task along with a DELETE to then delete the database.

The first part is pretty straightforward - here’s a function that, as long as the current user is an Admin and authenticated will retrieve the ‘token’ and pass it to another function.

   func getAdminToken() {
        if let currentUser = SyncUser.current {
            let refreshAdminToken = currentUser.refreshToken
            self.performDeleteRequest(authToken: refreshAdminToken!)
        }
    }

In the documentation, the refreshToken is sometimes referred to as MY_ADMIN_TOKEN or refresh token.

The second part of the task is to create a URLSession and send the data to the server to be deleted.

func performDeleteRequest(authToken: String) {
        let urlString = "https://your main realm url" //find this in RealmStudio Getting Started screen - something like https://your-project.us1.cloud.realm.io"
        let endPoint = "\(urlString)/realms/files/realm-to-delete"
        let url = URL(string: endPoint)
        var request = URLRequest(url: url!)
        request.httpMethod = "DELETE"
        request.addValue(authToken, forHTTPHeaderField: "Authorization")
        
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if let err = error {
                print("err = \(err.localizedDescription)")
                return
            }
            
            print("Realm has been deleted")
        }
        task.resume()
    }
}

This essentially constructs a command and authentication string to the server to delete the realm-to-delete

This next bit is not required to use the above code but since I’ve spent time doing all the research might as well share it. To drill down one level, if you take a look at the official documentation, it suggests a wget terminal command to do the delete. Here’s the correct command-line structure for this use case.

wget --method DELETE --header ‘Authorization: refreshAdminToken’ https://your–realm.us1.cloud.realm.io/realms/files/database-to-delete

One other thing is that wget command. It’s not in the macOS Terminal by default but you can very easily intall it using Homebrew.

and for completeness, once brew is installed

brew install wget