Allow dynamic root url on cordova #11402
Comments
|
Hi @crapthings , I'm not sure I follow what you want done here. Do you want to be able to set |
|
our cordova app can input any ddp server url, and we have a custom package that replace root_url. export const name = 'ddp-server-picker';
if (Meteor.isClient) {
const rootURL = window.localStorage.getItem('__root_url');
if (rootURL) {
__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL = rootURL;
__meteor_runtime_config__.ROOT_URL = rootURL;
}
console.log('__meteor_runtime_config__:', __meteor_runtime_config__);
} |
yes and make server url optional on build,have api change ddp connection,so when user reopen app they can use user specify root url,but not build one |
|
hot code push use root url from header if you dont override it. you might have infiniti reload if you meteor.connect to other ddp server |
|
@crapthings Since you already have a working code I would say that the best approach would be to go ahead and create a PR. |
|
Hey @crapthings, Check out #11408, integrated with Meteor 2.3. This PR fixes an issue with This is an undocumented feature of Meteor... meteor/docs#716 documents the feature after Meteor 2.3 releases. |
|
hi @brucejo75 it looks the ROOT_URL still point to mobileserverurl will this cause Meteor.absoluteurl() inconsistent with DDP_DEFAULT_CONNECTION_URL and autoupdate is always load code from rool url? the default Meteor.connection(ddp client) use DDP_DEFAULT_CONNECTION_URL so mongo collection and autoupdate use that too. when we want to switch DDP_DEFAULT_CONNECTION_URL, we can meteor.disconnect() first then metoer.connect(another ddp url), but after window.location.reload or reopen app, it still use ROOT_URL. imaging if meteor cordova app is just a empty shell without any default connection. METEOR_CORDOVA_COMPAT_VERSION_ANDROID=compat
METEOR_CORDOVA_COMPAT_VERSION_IOS=compat |
|
Hi @crapthings, I am having trouble understanding what your desired end state is. Please answer these questions...
There may be a way to accomplish this, but it is mostly a routing problem on a reverse proxy/file server. Comment on
|
|
apologize for my english.
the cordova runtime rooturl is load from cordova bundle index.html this is how cordova webapp works. current solutionwe can put these code before meteor connection initialize to override root url from hardcoded in head. so i think we can have an api builtin to cordova-webapp and allow optional root-url when build. |
|
Wow! That is really interesting. I am trying to manually replicate what your app does, but I cannot get it to work. Here is what I do: Repro AttemptIn my Cordova test app (
__meteor_runtime_config__.ROOT_URL="https://test2.com/"
__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL="https://test2.com/"
> __meteor_runtime_config__.ROOT_URL
"https://test2.com/"
> __meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL
"https://test2.com/"
> location.href
"http://localhost:12936/"
>
> window.location.reload()Comments
How do you make it reload and connect to |
|
I have a similar need though not exactly, in my case I have one backend meteor app that dishes out 2+ websites base off the URL with dynamic code eval. It works great at the browser level. https://ironcountytaxi.com/ and https://www.stgshuttle.com/ are both run from the same Meteor App. |
|
I am looking at your apps...
I see 3 different IP addresses for https://ironcountytaxi.com, https://stgshuttle.com & https://mobile.stgshuttle.com (your ROOT_URL) I assume you are running a reverse proxy and simply routing each domain to the same backend? & they all share the same
Somehow you key off the domain of the app to download different pages? Is that the dynamic code eval? If you are running a reverse proxy, do you need to really set the same ROOT_URL the same for each domain? Using the reverse proxy would essentially route everything to 1 server anyway? With a reverse proxy a DDP connection to ironcountytaxi.com would be the same connection as stgshuttle.com & mobile.stgshuttle.com. A cordova app is a little trickier because you need to set the |
Correct, but the backend only sends the modules that each URL needs, based off the URL, so I am not using a reverse proxy, all the URLs are pointing to the same IP cluster and it is all handled by the Meteor app.
That is exactly my problem, if I build multiple mobile apps, (which is what I want to do) and give each one a different I hope this makes sense, I know I can just make multiple meteor instances, each with it's own RootURL and connected to the same DB, but since we are talking about dynamically changeing the RootURL and default-ddp-connection, I think it will solve this issue. |
|
I am using |
|
@jamesgibson14, would you be at all interested in a zoom session? I want to make sure I understand what you want, I have been rooting around in this area for the last couple of weeks... I am not groking why you could not use the same |
|
I would be happy to jump on a zoom call if you need. |
|
Is my email in my github profile? you can send me a direct email. And we can set up a zoom. |
|
I don't see it, but here: sparhawk14@gmail.com, I already get a ton of spam so a little more won't hurt. :) |
|
Sent invite |
|
OK, I think that I understand the request a lot better... When Meteor serves up index pages What is needed is that the server should be able to be "hooked" so that on a particular request the |
|
I put some changes into Yesterday I got some time to test it for each of your scenarios and it worked for me. To try it out:
3 new APIs were added, check the documentation in the README for the I was never able to make your scenario work without this feature. I would be interested in how you got it to work. Without this feature I had to use this feature, plus the |
|
Let me know when you have tried it. I will submit a PR if you are successful. |
|
@brucejo75 will test it~ |
|
@jamesgibson14, @crapthings, any progress? |
|
hey @brucejo75 const cache = {
'web.browser': [],
'web.browser.legacy': [],
'web.cordova': [],
};
const hostValues = ['192.168.1.53:3000', '192.168.1.53:4000'];
WebApp.addRuntimeConfigHook((arch, request, encodedCurrentConfig, updated) => {
if(updated) {
// calculate the cache of config values you would like to return
const config = WebApp.decodeRuntimeConfig(encodedCurrentConfig);
console.log(config)
hostValues.forEach((h) => {
// Set the ROOT_URL to the value of the request host
// & cache the encoded value
config.ROOT_URL = `http://${h}`;
// add another value
config.newVar = 'some value';
cache[arch][h] = WebApp.encodeRuntimeConfig(config);
})
}
// will return cached ROOT_URL & newVar for this host request
// unless it is an unknown host request then it
// returns undefined and does nothing
return cache[arch][request.host];
}); |
|
@brucejo75 request.host is undefined? do you mean request.headers.host? in README.md, i see host only in request.headers. after i change to request.headers.host, i can see newVar. but i still can't make this working.
the problem that client request.headers.host is still current domain. but the root url seems changed, but got infinite reloading. Meteor.onConnection(() => {
console.log('onConnection')
})
const cache = {
'web.browser': [],
'web.browser.legacy': [],
'web.cordova': [],
};
const hostValues = ['192.168.1.53:3000', '192.168.1.53:4000'];
WebApp.addRuntimeConfigHook((arch, request, encodedCurrentConfig, updated) => {
console.log(request)
if(updated) {
// calculate the cache of config values you would like to return
const config = WebApp.decodeRuntimeConfig(encodedCurrentConfig);
console.log('config', config)
hostValues.forEach((h) => {
// Set the ROOT_URL to the value of the request host
// & cache the encoded value
config.ROOT_URL = `http://192.168.1.53:4000`;
// add another value
config.newVar = 'some value';
cache[arch][h] = WebApp.encodeRuntimeConfig(config);
})
}
// will return cached ROOT_URL & newVar for this host request
// unless it is an unknown host request then it
// returns undefined and does nothing
console.log('after config', cache[arch][request.headers.host])
return cache[arch][request.headers.host];
});Updatealmost there, the only thing i can think is proxy current request to app2. app1 ip:3000 app1 click a button to switch app2 then reload current tab. |
|
re: request.headers.host, thanks for the catch! I have updated the README. |
|
@crapthings, the hook is intended to accomplish any changes that you want. I was expecting that for your scenario, you would:
|
|
yes i think it should work for cordova, i will make an repo to demostrate after home
|
|
It is a mistake to use my sample code verbatim for your scenario. My sample code is addressing how to use the API, not any particular scenarios (that is up to you to figure out). NOTE: For your scenario you essentially want to send only 1 root response from app1:cordovaID that has
For cordova: autoupdate should just work once you have connected to app2 server.
That is really up to you? Cookie could work, but I would try using a standard How I tested your scenarioThis is what I did to test your scenario for cordova: on app1:
I did not test this scenario on the regular webapp (e.g |
|
@brucejo75 @crapthings see my comment here #11506 (review) because maybe it could also provide new insights to you. I can detail more the solution that I currently use in my Cordova apps with multiple backends if you want to |
|
Thanks @filipenevola for looking at this closely! If I understand your solution using app preferences, you are using app preferences to set global parameters like Could it be possible you are modifying what Issue 1If the app preferences solution as what I describe above, then I think you are describing the failed solution I describe in my Motivation writeup of the pull request. This is because it is Issue 2Secondly, I think you are questioning why there might be multiple
Neither one of these scenarios can work with 1 Other solutionsI can imagine other solutions to this issue, e.g. provide an override variable that And this is really a set of edge cases not a mainline case for Meteor. So I thought a hook solution would be the best route. |
|
Hi @brucejo75 I'm not questioning your solution at all. I was just explaining how I solve in my apps without your change but your change is good. And no, my solution is not like you are describing. Think about an event app hosted at myevents.com, on web we can have multiple domains on Galaxy and you can get this information from your connection to delivery a different content to each event domain but in Cordova that is not possible (just one ROOT_URL) so what I do is to have a setting in my config.xml for each event providing the I hope this makes more sense now. But I don't want to change your solution, I was just explaining how I'm solving this problem without your solution. |
|
Sorry @filipenevola didn't mean to sound so demanding, I was hoping you had a better solution! Thanks for the explanation of your solution, that makes sense. But still only 1 Thanks again! |
|
Hi @brucejo75, I am sorry I haven't replied, I did get a chance to read through your example and code and it looks like it will meet the requirements for my projects. Unfortunately I haven't had a chance to test it, I have been really busy with some clients going live. I hope to actually test it out in the next week or two, and give you more feedback. |
yes, without dynamic root_url, the default ddp connection(instance) that always point to built one. we can simply disconnect default connection like Meteor.disconnect()
Meteor.connect(newDDPUrl)but when you reload browser on desktop or cordova, the root_url will replaced by the original one from meteor_runtime_config. our app use kinda hacky solution that rewrite default root url by place a meteor package before ddp get connected. https://github.com/crapthings/meteor-switch-root-url so we don't have to specify root url when build cordova, user can input servername on login page if they known. so this pr #11506 enable dynamic root url. |
|
#11506 will be released as part of Meteor 2.4 |



meteor build ../youcordovabuild --directory
"Supply the server hostname and port in the --server option for mobile app builds."
optional ROOT_URL with cordova build
load default ROOT_URL with localStorage, fallback to built one if not
The text was updated successfully, but these errors were encountered: