Sitelet https://web.archive.org/web/20210911102717/https://github.com/meteor/meteor/issues/11402
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow dynamic root url on cordova #11402

Closed
crapthings opened this issue Apr 29, 2021 · 38 comments
Closed

Allow dynamic root url on cordova #11402

crapthings opened this issue Apr 29, 2021 · 38 comments

Comments

@crapthings
Copy link

@crapthings crapthings commented Apr 29, 2021

meteor build ../youcordovabuild --directory
"Supply the server hostname and port in the --server option for mobile app builds."

https://github.com/meteor/meteor/blob/devel/packages/boilerplate-generator/template-web.cordova.js#L39

optional ROOT_URL with cordova build

load default ROOT_URL with localStorage, fallback to built one if not

@StorytellerCZ
Copy link
Contributor

@StorytellerCZ StorytellerCZ commented Apr 29, 2021

Hi @crapthings , I'm not sure I follow what you want done here. Do you want to be able to set ROOT_URL which then would take the place of --server flag if it was not defined?

@crapthings
Copy link
Author

@crapthings crapthings commented Apr 29, 2021

our cordova app can input any ddp server url, and we have a custom package that replace root_url.
and this package load before ddp connection init so we can replace ROOT_URL, but i think its better support with meteor itself.

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__);
}

image

@crapthings
Copy link
Author

@crapthings crapthings commented Apr 29, 2021

Hi @crapthings , I'm not sure I follow what you want done here. Do you want to be able to set ROOT_URL which then would take the place of --server flag if it was not defined?

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

@crapthings
Copy link
Author

@crapthings crapthings commented Apr 29, 2021 •

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

@StorytellerCZ
Copy link
Contributor

@StorytellerCZ StorytellerCZ commented May 11, 2021

@crapthings Since you already have a working code I would say that the best approach would be to go ahead and create a PR.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 12, 2021

Hey @crapthings,

Check out #11408, integrated with Meteor 2.3.

This PR fixes an issue with cordova not picking up the value of DDP_DEFAULT_CONNECTION_URL. This will give you a lot more control of the DDP connection and the root connection for all platforms.

This is an undocumented feature of Meteor...

meteor/docs#716 documents the feature after Meteor 2.3 releases.

See: https://github.com/brucejo75/docs/blob/brucejo75/document_DDP_DEFAULT_CONNECTION_URL/source/environment-variables.md#ddp_default_connection_url

@crapthings
Copy link
Author

@crapthings crapthings commented May 13, 2021 •

hi @brucejo75

it looks the ROOT_URL still point to mobileserverurl

https://github.com/meteor/meteor/pull/11408/files#diff-518ab393bac19c51e12bc5236b52b494feddea86481eb077e9ee3dd88e6e36a6R496

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.
user can input specify ddp server then switch between them.

METEOR_CORDOVA_COMPAT_VERSION_ANDROID=compat
METEOR_CORDOVA_COMPAT_VERSION_IOS=compat

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 13, 2021 •

Hi @crapthings, I am having trouble understanding what your desired end state is.

Please answer these questions...

  1. Do you want to be able to dynamically change the ROOT_URL & dynamically change the DDP_DEFAULT_CONNECTION_URL? & you expect that the app will reload with the new ROOT_URL & DDP_DEFAULT_CONNECTION_URL.

  2. Do you have multiple Meteor servers running at these root urls that your user can change to?

  3. Do you want to reuse the same client code but just have it connect to different meteor servers? (without having to build the client for each server and manage that)

  4. Do you run a server like Nginx, Apache or Caddyserver in front of Meteor?

There may be a way to accomplish this, but it is mostly a routing problem on a reverse proxy/file server.

Comment on ROOT_URL & DDP_DEFAULT_CONNECTION_URL

If that is your question, then I do not think that is the intended use for ROOT_URL or DDP_DEFAULT_CONNECTION_URL.

When meteor builds it has no idea what the root url is for the site that the app is being built for. So setting the ROOT_URL essentially informs meteor that all calls to the root of your app can use that value and it is available to developers via Meteor.absoluteurl(). Meteor does not define the root URL for your page, it just wants to know where to send requests to your root.

The DDP_DEFAULT_CONNECTION_URL can be changed and it will connect with the new server for DDP calls.

Other comments

To change the url that your webpage is connecting to try this in your browser console:

window.location
window.location.href="<your new URL>"

The fields in window.location define the root of the webpage and where it will connect. When you enter a new href essentially it jumps to that page. Root you go to will load a new page.

The page from https://x.com cannot run the same code while pointing to https://y.com. That would violate very HTTP security rule. The code needs to be served from the domain you switch to.

@crapthings
Copy link
Author

@crapthings crapthings commented May 13, 2021 •

apologize for my english.
i will try to explain.

  • 1. Do you want to be able to dynamically change the ROOT_URL & dynamically change the DDP_DEFAULT_CONNECTION_URL? & you expect that the app will reload with the new ROOT_URL & DDP_DEFAULT_CONNECTION_URL.

yes we need change both in cordova, because when u reopen the app, or call window.location.reload() in cordova, it should use last rooturl and DDP_DEFAULT_CONNECTION_URL that user specify (we current use localStorage to save user rooturl, it override cordova webapp load rooturl info from head).

  • 2. Do you have multiple Meteor servers running at these root urls that your user can change to?
app1.domain.com app1
app2.domain.com app1
app3.domain.com app2
app4.domain.com app3

yes, even these server are not same app (client and server all different code) that made by meteor. we can use
METEOR_CORDOVA_COMPAT_VERSION to make AUTOUPDATE(HOT CODE RELOAD) working with these server.

METEOR_CORDOVA_COMPAT_VERSION_ANDROID=compat
METEOR_CORDOVA_COMPAT_VERSION_IOS=compat
  • 3. Do you want to reuse the same client code but just have it connect to different meteor servers? (without having to build the client for each server and manage that)

not completely, like 2. it can be different client code after HOT CODE RELOAD

  • 4. Do you run a server like Nginx, Apache or Caddyserver in front of Meteor?

yes but we don't do anything smart here, its just a simple reverse proxy. its not related. we can have meteor node running on 80 without proxy.

the cordova runtime rooturl is load from cordova bundle index.html

image

<script type="text/javascript">
  __meteor_runtime_config__ = JSON.parse(decodeURIComponent("%7B%22meteorRelease%22%3A%22METEOR%402.2%22%2C%22gitCommitHash%22%3A%2277c5eaff00fabd58100ffb3193a648c0bcf07242%22%2C%22ROOT_URL%22%3A%22https%3A%2F%2Fapp1.domain.com%2F%22%2C%22ROOT_URL_PATH_PREFIX%22%3A%22%22%2C%22DDP_DEFAULT_CONNECTION_URL%22%3A%22https%3A%2F%2Fapp1.domain.com%2F%22%2C%22autoupdate%22%3A%7B%22versions%22%3A%7B%22web.cordova%22%3A%7B%22version%22%3A%224a07418993c37b3786a7afb5931e23eeba19c99b%22%2C%22versionRefreshable%22%3A%229716ea65d36741f6c3e3ebe1b08e937581a45d89%22%2C%22versionNonRefreshable%22%3A%22e34793622fbac620871168bca3ade04f5a3280be%22%7D%7D%7D%2C%22appId%22%3A%221nvzc9t1g8s5a913jvzlw%22%2C%22meteorEnv%22%3A%7B%22NODE_ENV%22%3A%22production%22%2C%22TEST_METADATA%22%3A%22%7B%7D%22%7D%7D"));
  if (/Android/i.test(navigator.userAgent)) {
    if (!__meteor_runtime_config__.httpProxyPort) {
      __meteor_runtime_config__.ROOT_URL = (__meteor_runtime_config__.ROOT_URL || '').replace(/localhost/i, '10.0.2.2');
      __meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL = (__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL || '').replace(/localhost/i, '10.0.2.2');
    }
  }
</script>

https://github.com/meteor/cordova-plugin-meteor-webapp/blob/52bfb0d308096cab26074ebc478259676827508c/src/ios/AssetBundle.swift#L3

this is how cordova webapp works.

current solution

we can put these code before meteor connection initialize to override root url from hardcoded in head.
this works but more like a hack that u should know how meteor own package system load order.

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__);

image

so i think we can have an api builtin to cordova-webapp and allow optional root-url when build.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 13, 2021 •

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 Attempt

In my Cordova test app (ROOT_URL=https://test1.com)

  1. Put a breakpoint in the code right after __meteor_runtime_config__ is initialized.
  2. Reload the app.
  3. When I stop at the breakpoint, I am right at the beginning of the page load. Here I do this in the console:
__meteor_runtime_config__.ROOT_URL="https://test2.com/"
__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL="https://test2.com/"
  1. Then I let the program continue.
  2. After Meteor completes initialization I do this in the console:
> __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

  • I have updated ROOT_URL && DDP_DEFAULT_CONNECTION_URL & they are set to "https://test2.com/"
  • location.href is pointing to localhost, "http://localhost:12936/"
  • When I restart (to try to load the app at https://test2.com) it reloads "http://localhost:12936/" which loads the cached bundle that has ROOT_URL: "https://test1.com"
  • Also, because cordova-plugin-meteor-webapp reads the __meteor_runtime_config__ settings directly from the index.html file I do not think that it sees the new ROOT_URL and reuses the initialized ROOT_URL: "https://test1.com"

How do you make it reload and connect to https://test2.com? Am I missing a step?

@jamesgibson14
Copy link

@jamesgibson14 jamesgibson14 commented May 14, 2021

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.
However I can't create 2 separate cordova apps for these 2 sites because I can only have 1 RootUrl and 1 defaultDDPConnection.
I would love to be able to adjust the RootUrl and DefaultDDPConnection for each request to webapp.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 14, 2021 •

@jamesgibson14,

I am looking at your apps...

I have one backend meteor app that dishes out 2+ websites base off the URL

I see 3 different IP addresses for https://ironcountytaxi.com, https://stgshuttle.com & https://mobile.stgshuttle.com (your ROOT_URL)
But... each separate address is dishing up the same meteor bundle: https://www.stgshuttle.com/69f38b8dd2d7bb931ef487988dfc5af7308d9810.js
https://www.ironcountytaxi.com/69f38b8dd2d7bb931ef487988dfc5af7308d9810.js
https://mobile.stgshuttle.com/69f38b8dd2d7bb931ef487988dfc5af7308d9810.js
All domains refer to the same appId: "skatqz1aj5raw10y3fuu"

I assume you are running a reverse proxy and simply routing each domain to the same backend? & they all share the same ROOT_URL which will connect them to the same backend for DDP operations.

with dynamic code eval

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 ROOT_URL via the --server flag at build time. Wouldn't building 2 cordova apps each with a different server work?

@jamesgibson14
Copy link

@jamesgibson14 jamesgibson14 commented May 14, 2021

But... each separate address is dishing up the same meteor bundle:

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.

A cordova app is a little trickier because you need to set the ROOT_URL via the --server flag at build time

That is exactly my problem, if I build multiple mobile apps, (which is what I want to do) and give each one a different --server ie customer-mobile.ironcountytaxi.com and driver-mobile.ironcountytaxi.com it won't work because the backend can only have one RootURL with dishes out the main bundle and the default-ddp-connection, so then my backend doesn't know which dynamic modules to send.

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.

@jamesgibson14
Copy link

@jamesgibson14 jamesgibson14 commented May 14, 2021 •

I am using WebApp.connectHandlers to "inject" the dynamic modules based off the URL on the first load and then the ddp connection after that.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 14, 2021

@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 WebApp.connectHandlers technique for the mobile domains.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 14, 2021

@jamesgibson14
Copy link

@jamesgibson14 jamesgibson14 commented May 14, 2021 •

I would be happy to jump on a zoom call if you need.
It has been a while since I was digging into the Meteor code trying to figure it out, but yes that looks like the right area.
Obviously I never did find a solution.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 14, 2021 •

Is my email in my github profile? you can send me a direct email. And we can set up a zoom.

@jamesgibson14
Copy link

@jamesgibson14 jamesgibson14 commented May 14, 2021 •

I don't see it, but here: sparhawk14@gmail.com, I already get a ton of spam so a little more won't hurt. :)

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 14, 2021

Sent invite

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 14, 2021

OK, I think that I understand the request a lot better...

When Meteor serves up index pages ROOT_URL and DDP_DEFAULT_CONNECTION_URL are statically set by the Meteor for that server.

What is needed is that the server should be able to be "hooked" so that on a particular request the ROOT_URL and the DDP_DEFAULT_CONNECTION_URL can be set.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 23, 2021 •

@jamesgibson14, @crapthings,

I put some changes into webapp which should allow for dynamic changing of ROOT_URL & DDP_DEFAULT_CONNECTION_URL (or any __meteor_runtime_config__ field). This feature only works if you allow inline eval. The reason is otherwise meteor just sends down a pre-stored file: meteor_runtime_config.js.

Yesterday I got some time to test it for each of your scenarios and it worked for me.

To try it out:

git clone --branch brucejo75/dynamic_runtime_config https://github.com/brucejo75/webapp into your shared packages directory, This will override meteor's webapp.

3 new APIs were added, check the documentation in the README for the brucejo75/dynamic_runtime_config branch.

@crapthings,

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 cordova-plugin-meteor-webapp will query for the root and get back the default __meteor_runtime_config__ which does not have the updated ROOT_URL. Your package only updates the ROOT_URL in the client value after that.

I had to use this feature, plus the METEOR_CORDOVA_COMPAT_VERSION_ trick, and I had to give each application the same appId.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented May 23, 2021

@jamesgibson14, @crapthings,

Let me know when you have tried it. I will submit a PR if you are successful.

@crapthings
Copy link
Author

@crapthings crapthings commented May 24, 2021

@brucejo75 will test it~

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented Jun 9, 2021

@jamesgibson14, @crapthings, any progress?

@crapthings
Copy link
Author

@crapthings crapthings commented Jun 10, 2021 •

hey @brucejo75
i've paste these to server, but i didn't see newVar

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];
});

@crapthings
Copy link
Author

@crapthings crapthings commented Jun 10, 2021 •

@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.

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 cordova-plugin-meteor-webapp will query for the root and get back the default meteor_runtime_config which does not have the updated ROOT_URL. Your package only updates the ROOT_URL in the client value after that.

I had to use this feature, plus the METEOR_CORDOVA_COMPAT_VERSION_ trick, and I had to give each application the same appId.

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];
});

Update

almost there, the only thing i can think is proxy current request to app2.

app1 ip:3000
app2 ip:4000

app1 click a button to switch app2 then reload current tab.
the current location is still ip:3000, but maybe we can send something along with request in headers that specify i want to load app2.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented Jun 10, 2021

re: request.headers.host, thanks for the catch! I have updated the README.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented Jun 10, 2021 •

@crapthings, the hook is intended to accomplish any changes that you want.

I was expecting that for your scenario, you would:

  1. Accept user input that you wanted to change the app.
  2. Send a request to the server, maybe via a Meteor method? to set the app to the new url
  3. on the server side accept the request to change the ROOT app and modify your response in WebApp.addRuntimeConfig.
  4. on completion of the method the client would then restart.
  5. then WebApp.addRuntimeConfig would respond with a new ROOT_URL. And the app would connect to the different server.

@crapthings
Copy link
Author

@crapthings crapthings commented Jun 10, 2021 •

@brucejo75

yes i think it should work for cordova, i will make an repo to demostrate after home

  1. is it possible to enhance it that support inbrowser, make autoupdate work with new rooturl.
    in my test project, the initial html is still sending with request one, the ddp request is send to another one which is right.

  2. how to let server know which runtimeconfig to send? by cookie?

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented Jun 10, 2021

@crapthings,

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 ROOT_URL set to app2

  • you do not want to send all responses from app1:cordovaID to have ROOT_URL set to app2 because when you go back to app1 from app2 your ROOT_URL will be set to go back to app2 which will cause infinite reloading.
  • you also only want to only do this for a specific user/device. Not all users.
  • cordova only, webapp is much simpler to accomplish without changing ROOT_URL.
  1. is it possible to enhance it that support inbrowser, make autoupdate work with new rooturl.
    in my test project, the initial html is still sending with request one, the ddp request is send to another one which is right

For cordova: autoupdate should just work once you have connected to app2 server.

  1. how to let server know which runtimeconfig to send? by cookie?

That is really up to you? Cookie could work, but I would try using a standard Meteor.method passing your cordovaID & new ROOT_URL to the server.

How I tested your scenario

This is what I did to test your scenario for cordova: on app1:

  • send the request to change to app1 via a Meteor.method. On the server side you need to change the cache for the response. In my test I changed it globally(for all users & all sessions).
  • When the Meteor.method completes is when you then do a location.reload().
  • location.reload() will cause cordova-plugin-meteor-webapp to:
    a. make a root request at current ROOT_URL app1. This comes down with the ROOT_URL set to app2.
    b. make a manifest request to the new ROOT_URL: app2.
    c. once it loads the new manifest the app is now app2.

I did not test this scenario on the regular webapp (e.g web.browser). On a regular webapp you do not need to change the ROOT_URL, etc. You can just change the location.href when you user wants to change apps (much simpler).

@filipenevola
Copy link
Member

@filipenevola filipenevola commented Jul 7, 2021

@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 😉

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented Jul 7, 2021

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 ROOT_URL at startup. PLEASE CORRECT ME IF I AM WRONG.

Could it be possible you are modifying what cordova-plugin-meteor-webapp sees as ROOT_URL through app preferences? Here are the only references to ROOT_URL I see for the android version and it is only set by the runtimeConfig.

Issue 1

If 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 cordova-plugin-meteor-webapp that is getting its ROOT_URL from any downloaded index file and cordova-plugin-meteor-webapp manages all app file downloads (*.css, *.js) that are described in the manifest.json. Working around this trait of cordova-plugin-meteor-webapp is impossible without modifying the ROOT_URL that the server emits in the runtimeConfg.

Issue 2

Secondly, I think you are questioning why there might be multiple ROOT_URLs when one could do the trick. There are 2 scenarios in this issue:

  • @crapthings describes a system where he has 1 cordova app and multiple backend servers. So he needs a different ROOT_URL for each server.
  • @jamesgibson14 describes a system where he has 1 cordova app & 1 server app. But in the server he can respond to multiple origin requests with different applications. I think you suggest this problem could be solved without resorting to different origins. But I think @jamesgibson14 needs to use the origin as a discriminator because he supplies the same solution to multiple customers that obviously have different origins.

Neither one of these scenarios can work with 1 ROOT_URL that I can tell. Ideas?

Other solutions

I can imagine other solutions to this issue, e.g. provide an override variable that cordova-plugin-meteor-webapp could read instead of ROOT_URL.
But the more I work with __meteor_runtime_config__ the more I appreciate the ability to modify the values in it at runtime.

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.

@filipenevola
Copy link
Member

@filipenevola filipenevola commented Jul 7, 2021

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 eventId so I provide this on every Meteor.call and Meteor.subscribe and then I can provide a different response based in the eventId.

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.

@brucejo75
Copy link
Contributor

@brucejo75 brucejo75 commented Jul 7, 2021

Sorry @filipenevola didn't mean to sound so demanding, I was hoping you had a better solution! 😸
And I was looking for some feedback re:my solution.

Thanks for the explanation of your solution, that makes sense. But still only 1 ROOT_URL. So unfortunately, something like the PR is required to handle the scenarios above... 😞

Thanks again!

@jamesgibson14
Copy link

@jamesgibson14 jamesgibson14 commented Jul 7, 2021

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.

@StorytellerCZ StorytellerCZ linked a pull request that will close this issue Jul 7, 2021
@crapthings
Copy link
Author

@crapthings crapthings commented Jul 8, 2021 •

@crapthings describes a system where he has 1 cordova app and multiple backend servers. So he needs a different ROOT_URL for each server.

yes, without dynamic root_url, the default ddp connection(instance) that always point to built one.
when we don't want to multiple ddp connections(instances), we just want to switch the ddp to specify 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.

@StorytellerCZ
Copy link
Contributor

@StorytellerCZ StorytellerCZ commented Sep 1, 2021

#11506 will be released as part of Meteor 2.4

@filipenevola filipenevola added this to the Release 2.4 milestone Sep 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

5 participants