-
Notifications
You must be signed in to change notification settings - Fork 1k
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
bug: service worker server.url not injecting capacitor #5278
Comments
It actually seems that the capacitor script is not being injected after the site is served by a service worker. I have included this on Android but still getting plugin errors: I don't believe that this works any more. The site is picking up that its running on Android through a service worker: |
Silly question, but for a workaround, it is possible to inject capacitor script manually? |
The issue, anyone have a workaround? |
Please see a repo here: https://github.com/happendev/TestCapacitor The PWA site is hosted on https://testapp.happen.zone. Android:
Maybe I have done something wrong? |
I have yet to do some additional testing, but I hope this issue is not the same on iOS. |
This comment has been minimized.
This comment has been minimized.
@dylanvdmerwe I started looking into what should be done in order to support this use case (I'll need it as well). This is what we talked about with @thomasvidas on Discord : me : @thomasvidas : @dylanvdmerwe Did you test on iOS a well? |
@jgoux I have tried to get a service worker working so I can test this on iOS - but I did not come right with whatever needs to be enabled for this. Does anyone know what I missed in the repo? I would love to check out how the service worker is affected on iOS as well as part of this. Or is there another repo where this works that I can use for testing? |
I'm facing this "problem" too.... As a temporary "workaround" (in order to solve this), I force a site reload when the ServiceWorker is Ready. I know and I also don't like the solution, but I needed to implement this 💩 while this "issue/bug/feature" is addressed.
This code is working for me, at the time as I write this... (is working on production). Forgive me... 😂 |
Using this kind of functionality is primarily not for the app stores in our case, we really want to use this for apps that are rolled out (enterprise) to operators and employees at our clients. This would drastically reduce the building required to deploy updates to them, as all we would need to do is update the PWA. Please advise if there is anything that I can do to assist or test to get |
@jgoux Do you have any more feedback on the way forward on this? Has anyone tried anything further as we would think this kind of thing would be incredible to get working through Capacitor apps. |
@dylanvdmerwe Hello Dylan, I didn't have time to investigate yet. Did you already try this solution : https://stackoverflow.com/a/55916297/1728627 ? I believe @mhjam made a contribution to make it works here : #1465, maybe he knows more about it? 😄 |
Nope, It's not working anymore. |
If the path your service worker is loading contains a ".html" file extension, the the following update in WebViewLocalServer.handleProxyRequest() resolves the issue (if you also hook up a service worker client delegating to WebViewLocalServer like in https://stackoverflow.com/questions/62354423/how-to-use-serviceworkercontroller-on-android/63491172#63491172). Note that this is exactly the same hack that is in WebViewLocalServer.handleLocalRequest(), so if it's good enough for local requests it should be good enough for proxy ones too. I've opened a pull request for it: #5428
|
@chrisharris77 No this does not appear to work, at least not when using a normal ionic app as per my repo. https://github.com/happendev/TestCapacitor
|
Hi @xEsk, can you provide some more context, or a repo for this? I have tried, but even with this Capacitor is not initialized which means plugins don't work when loaded from the SW offline version. Any use of the plugins breaks. |
The first run (when not served by the service worker):
This is the service worker cached PWA version of the app running on Android device. As you can see, it still detects that the platform is Android and isNativePlatform is true. But it has not initialized any android plugin stuff which is why the plugins are breaking. Is there maybe a way to force Capacitor to run in 'web' mode here (as a true PWA), as then the plugins should work? Ideally it should setup itself correctly and run in proper Android mode. |
@dylanvdmerwe @webuniverseio @goforu @xEsk @chrisharris77 Any updates about this issue ? |
Is this part still working ? Thanks a lot ! |
Is there any permanent resolution to this issue to make service workers work with capacitor plugins on Android? It is very frustrating that my Ionic6/Angular13 app works nicely with the service worker on browser but fails to register the same on Android. When I implement the workaround suggested, service worker loads but capacitor plugins fail to load on the device. Please update when there is any resolution or workaround for this. |
This comment was marked as abuse.
This comment was marked as abuse.
Still nobody found a solution here ? |
I using this answer and work for me on android with capacitor 2. but I replace |
Thanks a lot @yoyo930021 I'm ready to pay someone as freelance to develop the supported module / fix for capacitor. |
Update: blocking network loads like so If there is anyone else using the 3rd party service worker for something other than caching I would be interested to know if it will load the other features without the request header present while "blocking network loads". It is not super clear how some of these settings are supposed to behave from the documentation. So I am trying to infer what I can. |
Update: I was assuming that the Service-Worker: script header was coming from the server but it was in the request. So I removed it and it did still run just without the conventional semantic understanding from the browser. Possibly observed another side effect that appears to cause the caching logic to infinitely loop on itself, at least in my particular 3rd party worker. Then I decided to modify the Accept header to match the initial requests' value which happened to have "text/html" in it while the worker was using In my case forcing the proxy to process it fixes the whole cache. So this will work for me. And I imagine it will help someone else too. Check your request headers for
|
I am also impacted by this. Any updates on whether or not this is on the roadmap? Thanks! |
I am also facing same issue. I have removed the service worker from my code. Still same. |
I've tried several of the above suggestions, including various changes to MainActivity.java, and none of them worked. I am using Webpack 4 + sw-precache-webpack-plugin. The basic I've also tried isolating all use of the plugin to a separate entry point that is not managed by the service worker, and loading it as an ES module ahead of the application. Still no luck (probably because the index.html is managed by a service worker). I imagine those who are more knowledgeable about Capacitor are laughing at me right now. My hack which others may be able to use is to toggle the service worker on/off by anticipating the user's needs (and reloading). This is far from ideal, as it means the users that depend on the plugin do not benefit from a service worker for the 95% of the time that they are not using the plugin's functionality. Overall, using Capacitor has been a positive experience. I just feel a bit uneasy as my primary reason for switching from Cordova (which worked fine with service workers) to Capacitor was for this particular plugin. |
Do you try to this idea? The |
Thanks @yoyo930021 , I just tried it again and it did not work. Java is not my forte, but when I do the following: public class MainActivity extends BridgeActivity {
private static final String TAG = "myapp";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "SDK_INT:" + Build.VERSION.SDK_INT);
if (Build.VERSION.SDK_INT >= 24) {
ServiceWorkerController swController = ServiceWorkerController.getInstance();
swController.setServiceWorkerClient(new ServiceWorkerClient() {
@Override
public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
Log.v(TAG, request.getUrl().toString());
if (request.getUrl().toString().contains("index.html")) {
request.getRequestHeaders().put("Accept", "text/html");
}
var result = bridge.getLocalServer().shouldInterceptRequest(request);
return result;
}
});
}
}
} the first |
Oops, just realized it wasn't logging because I had just disabled the service worker. Too many moving parts, LOL. When I reenable the service worker, the first URL logged is "https://MY_DOMAIN/service-worker.js"...I never see an "index.html", but since I configure the Capacitor URL for just "https://MY_DOMAIN" and that server responds with index.html, I'm not entirely surprised. The line immediately before mine is from the "Capacitor/Console" tag, "I", "File: https://MY_DOMAIN/ - Line 228 - Msg: undefined". 4/20/23 UPDATE: Now it is working. Despite the fact that "index.html" is never logged! I am going to do some more testing. 4/21/23 UPDATE: "index.html" is logged, just had trouble finding it in the sea of other data. So, in my case, the |
Hey everyone. I also ran into this issue a while ago, but successfully worked around it by adding the However, in the wild, I've got a very high volume Sentry error reporting that Has anyone else run into this? The same issue where the runtime isn't injected, but flaky instead of all the time. If not, I guess there must be something else wrong inside our service worker wrapper. EDIT: It was in fact something else wrong inside our service worker wrapper. We had some additional logic (🙃) to avoid weird interactions with in-app browsers, which was sometimes causing the |
Thanks a lot Henry, can give us more details about where you add the |
I suggest not attempting to enable service workers in capacitor android. Although there are various hacks available to make it function to some extent, in reality, it performs poorly. Known issues:
|
After working several hours on this I ended up with this solution working on capacitor 5. public class MainActivity extends BridgeActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
ServiceWorkerController swController = null;
swController = ServiceWorkerController.getInstance();
swController.setServiceWorkerClient(new ServiceWorkerClient() {
@Override
public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
if (request.getUrl().toString().contains("index.html")) {
request.getRequestHeaders().put("Accept", "text/html");
}
return bridge.getLocalServer().shouldInterceptRequest(request);
}
});
}
}
} |
Just for info - I can't confirm that. We're using SW successfully (with |
What about iOS? Does the service worker work the same as on Android within Capacitor ? |
I thought service workers were a staple of PWA's? The user-agent could be part of the problem. I remember considering that when I was working on this. Perhaps it can be addressed at the specification level. On second thought, probably not. I remember what the user-agent looked like now. It was very intentional. Definitely for the server to use. But in this case the client may need to be aware as well at a higher level. If I remember correctly I couldn't use it because it was inconsistently available between requests. That could be addressed at the spec level. |
In your case, I think stripe uses service workers anyway. I could be wrong, but I seem to remember that being the case. So you may want to try the same proxy bypass but load something else instead when offline? The proxy bypass I am referring to is the same one everyone seems to be using but modified for your case. |
It seems like these edge cases are going to be quite difficult to work with in Capacitor in general due to how the proxy is done. Maybe the better fix is to simply add something to the documentation about when/why/how to bypass the proxy to handle a given edge case? |
If it's not supported that's fine, but the Capacitor docs literally suggest using a Service Worker to make the webapp progressive when it's run in-browser, with no hint that it will break plugin functionality when run on native mobile. Perhaps we can add certain Capacitor-injection paths to a service worker's interception "exception list"? Also: disabling the service worker was not enough, to fix the "not implemented on android" errors. I also had to |
Actually, the service worker stays established and persists between sessions so long as the webview's storage is not cleared - in fact it's only on the second+ load of the app (with SW serving interceptions) that all my Capacitor plugins crash. If there are specific Capacitor injection scripts that we need to blocklist, that would be a good solution for now! |
Would be nice to have this included as part of Capacitor by default, many people will be able to save time. |
Hello everyone! :) I am having a similar issue.
How do I fix the issue? Please help! :( PS. already tried above codes and it didn't help. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Unfortunately I'm not able to include proprietary software or services in my app. I just want to update as soon as my CI builds a new static app on github pages, saving the app store updates for plugin changes - but also have offline support which Service Workers are perfect for (and is already working well in browsers). Since none of the workarounds here are working (unless you do SSR), in the mean time I will try to have a local startup file that grabs Capacitor and then hands it off to the app somehow |
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as abuse.
This comment was marked as abuse.
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out. |
Bug Report
Capacitor Version
Platform(s)
Current Behavior
Calling any native plugins when an app is served from an Angular service worker causes the plugins to fail. Using
![image](https://user-images.githubusercontent.com/2852839/143595172-71102760-69e3-403f-afbc-058dce62e1cc.png)
server.url
to load the site on Android.Platform ready does not help for this.
Expected Behavior
Capacitor needs to be injected when a site is served through a service worker.
Code Reproduction
app.module.ts
app-load-service.ts
The text was updated successfully, but these errors were encountered: