Dynamically change mobile-server variable

I’ve seen this asked a few times on this forum, but no answer…

Is there a way to dynamically change the mobile-server variable in a Cordova app?

I have a customer who needs to make sure all their data is stored within their own country (Australia). I can easily set up a private server for them on a different subdomain so they can use the website, but how can I avoid having to build completely separate iOS & Android apps and submit them to the app stores?

It would be better if I could let the server be changed from within the app…

Thanks!

A couple of options here.

First, if you don’t care about transit, only storage, you can do this entirly server side, using a shared mongo deployment. One shard deployed in Australia. One wherever your default is. You shard your data on client id. Even simpler if you don’t mind custom server deployments is you have a subdomain set up with its own db.

Your second option, if you need data to remain in Australia even in transit would be to detect that this was the case on login (or some other config) and disconnect the primary meteor connection, then reconnect on a different url. You could even save that url as a local setting for next time. The tricky part is coordinating login, automatic login (e.g., on re opening a site) happens before your client code loads, and is done transparently by meteor. It’s very difficult to intercept.

Thanks. I’m waiting for an answer from the customer on the data in transit question…

For the first option, I currently have a really cheap deployment with just a single $5 DO droplet with the server and mongo, deployed with mup. I have heaps of capacity before I need to worry about scaling. Is it possible to shard without paying heaps to an external mongo provider?

For the second option, are you referring to DDP.connect(url) to connect the app to the different url? I haven’t used that before, it looks like it returns separate subscribe/call methods which would then have to be used in my client code instead of the standard Meteor.subscribe/Meteor.call methods, is that correct? I understand what you mean about intercepting the automatic log in - do you have any solutions to that?

You can shard yourself, but there is no avoiding the additional servers. 3 config servers. Plus whatever you want for you replicaset. So most people go from 3 to 9 servers.

Regarding DDp.connect. That is one option. You could then wrap meteor.call and meteor.subscribe (and a few more) to use your new connection. Or you can actually force your main connection url to change. This is a little hacky, but I’ve used.it where I’ve had to in the past.

I don’t have a good solution on the login piece. You just have to wait for user to be present and loggingin to be false. Then recall login on the new connection.

1 Like

Hey @znewsham, I’ve managed to get something working with DDP.connect(), thanks for your help!

1 Like

Just for future reference, this thread was also very helpful.

Redirecting all of Meteor.subscribe/call/status/disconnect/reconnect was necessary for some of my app’s functionality, but as noted elsewhere this can break Hot Code Push. My solution to that is this:

Meteor.connection = Accounts.connection = DDP.connect(remoteURL);
['call', 'methods', 'apply', 'status', 'reconnect', 'disconnect'].forEach(name => {
	Meteor[name] = Meteor.connection[name].bind(Meteor.connection);
});
const _origSubscribe = Meteor.subscribe;
Meteor.subscribe = function() {
	// meteor_autoupdate_clientVersions subscription needs to stay on the original server for Hot Code Push to work
	return arguments[0]=='meteor_autoupdate_clientVersions' 
		? _origSubscribe.apply(this, arguments)
		: Meteor.connection.subscribe.apply(Meteor.connection, arguments);
}
Meteor.users = Accounts.users = new Meteor.Collection('users');
// create new Mongo collections for all my own collections...