expo: Recent increase in 'No matching activity' errors from `WebBrowser.openBrowserAsync()`
Summary
An app in production since August 2020 that launches a web browser using WebBrowser.openBrowserAsync()
is failing to do so without throwing ‘No matching activity’ errors on some Android devices, but with an increasing frequency during 2021 so far. It seems to be mostly affecting devices running Android 11 (a full list of device models is available).
Managed or bare workflow? If you have ios/
or android/
directories in your project, the answer is bare!
bare
What platform(s) does this occur on?
Android
SDK Version (managed workflow only)
No response
Environment
Expo CLI 3.28.5 environment info: System: OS: macOS 10.15.7 Shell: 5.7.1 - /bin/zsh Binaries: Node: 12.19.0 - /usr/local/bin/node npm: 6.14.11 - /usr/local/bin/npm Managers: CocoaPods: 1.10.1 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2 IDEs: Xcode: 12.4/12D4e - /usr/bin/xcodebuild npmPackages: expo: ^37.0.0 => 37.0.12 react: 16.9.0 => 16.9.0 react-dom: 16.9.0 => 16.9.0 react-native: 0.61.4 => 0.61.4 react-native-web: ^0.11.7 => 0.11.7 react-navigation: ^4.0.10 => 4.4.0 npmGlobalPackages: expo-cli: 3.28.5 Expo Workflow: bare
Reproducible demo or steps to reproduce from a blank project
...
try {
await WebBrowser.openBrowserAsync("https://www.google.co.uk");
} catch (e) {
console.error(e.message); // === "No matching activity"
}
The issue above is occurring with increasing frequency on an app in production on Expo 37. I am aware of WebBrowser.getCustomTabsSupportingBrowsersAsync()
which will be implemented to determine whether a browser is available before attempting to open one, but I would like to know why this may be suddenly occurring more often. A new version of the app on Expo 39 is not ready to be released but I am concerned that the problem will still persist. I am unable to replicate in the Emulator running Android 11.
For reference, the affected devices to date are:
- CPH2025
- J8110
- J8210
- Pixel 2
- Pixel 3
- Pixel 3a
- Pixel 5
- SM-F916B
- SM-G770F
- SM-G780F
- SM-G781B
- SM-G970F
- SM-G973F
- SM-G975F
- SM-G977B
- SM-G980F
- SM-G981B
- SM-G986B
- SM-G988B
- SM-G991B
- SM-G996B
- SM-G998B
- SM-N770F
- SM-N970F
- SM-N975F
- SM-N976B
- SM-N980F
- SM-N981B
- SM-N986B
- T799H
- XQ-AT51
- XQ-AU51
- XQ-AU52
Unfortunately OS versions are not currently logged in the version of the app in production but my suspicion is that these are Android 11.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 15
- Comments: 66 (15 by maintainers)
I’m experiencing the same issue. It fails randomly on Android devices. Expo 41.
This issue is, in fact, not stale
Found out the Solution Guys:
https://developer.android.com/training/package-visibility/use-cases
Just add:
<queries> <intent> <action android:name="android.support.customtabs.action.CustomTabsService" /> </intent> </queries>
into AndroidManifest
Before: {“browserPackages”: [], “defaultBrowserPackage”: null, “preferredBrowserPackage”: null, “servicePackages”: []}
After: {“browserPackages”: [“com.android.chrome”], “defaultBrowserPackage”: “com.android.chrome”, “preferredBrowserPackage”: “com.android.chrome”, “servicePackages”: [“com.android.chrome”]}
it was required in Android 11 (API level 30) or higher.
This was working for me, but now trying to push a new build, Google Play Store requires 30 as of today, so this is a bit of a problem.
@hixus I had the same issue for Android only, found the solution: it turned out you can pass the
browserPackage
as an option with the name of a browser, which you can get fromWebBrowser.getCustomTabsSupportingBrowsersAsync()
. Complete code:My users were also experiencing this. I was able to track this back to a single commit where we bumped Android API version target from
29
to30
.So going back to
29
resolved the issue for us:build.gradle
Edit: This workaround no longer works, since targeting API
30
is now mandatory.for what it’s worth - this happened to me because I was using an android emulator that did not have a browser. To fix this, I installed an emulator that had the play store included with the emulator. This emulator had chrome installed out of the box and this error went away.
Hey @giautm , Getting this output for tabsSupportingBrowsers { defaultBrowserPackage: null, servicePackages: [ ‘com.android.chrome’ ], browserPackages: [], preferredBrowserPackage: null }
In my case, I had to:
AndroidManifest.xml
, add:android/build.gradle
andandroid/gradle/wrapper/gradle-wrapper.properties
files: https://github.com/lukasgit/flutter_contacts/issues/220#issuecomment-1061725322We are seeing this on some Android 11 devices when the user has the DuckDuckGo app set as their default browser. It seems that DuckDuckGo does not support the Custom Tabs Service and thus is not included in the
servicePackages
returned byWebBrowser.getCustomTabsSupportingBrowsersAsync
, which causesdefaultBrowserPackage
to be null. This helper is not actually used byopenBrowserAsync
, but as best I can tell it effectively does the same sort of intent lookup and ultimately comes to the conclusion that DuckDuckGo as a default browser cannot be used as an auth session browser.If the user 1) changes their default browser, 2) uninstalls DuckDuckGo, or 3) has DuckDuckGo installed without a default browser being selected, then
openBrowserAsync
works as expected. I was able to reproduce the issue and the user-initiated resolutions in a Pixel 4 API 30 emulator with DuckDuckGo, Chrome, and the OS default web browser installed. I’m not sure if this is an Expo bug necessarily, but it definitely seems wrong that although there are browsers available that could work as an auth session browser (Chrome in this case), the attempt fails seemingly because the default browser does not meet the requirements.A development-driven solution that appears to work is adding
to our app’s manifest file (following this post linked above). This is obviously a very specific and poor solution, but it may help determine how to approach the intent resolution issue.
I’ve noticed this error on newer versions of Android when attempting to open a URL with no protocol. Prefixing with https:// when missing fixed it for me.
You can pick the first element of browserPackages to use.
@giautm I’m on
expo-web-browser
version8.0.0
. I haven’t tried upgrading yet though.Ah nice! Iam currently in a lower version (“expo-web-browser”: “^8.6.0”), I can’t update right now because of the new dependencies.
The latest question: what’s version of expo-web-browser in your app?
In the version 10.1.0 they have the intent in the manifest: https://github.com/expo/expo/blob/main/packages/expo-web-browser/android/src/main/AndroidManifest.xml
Yea, Vanilla RN Project, so we need to manually add it.
I think managed doesn’t need because expo control it, but it should be updated in expo packages (if ins’t)
And on bare workflow I guess it should be done manually either
Hey, we still with that problem!?
{“browserPackages”: [], “defaultBrowserPackage”: null, “preferredBrowserPackage”: null, “servicePackages”: []}
I am testing on a simulator Android 11, it has with Chrome selected to be the default browser.
Seems ios exception is the one from line 55 (
The method or property WebBrowser.getCustomTabsSupportingBrowsersAsync is not available on ios, are you sure you've linked all the native dependencies properly
), so that should be moved to else clause or removed completely.Thanks for solution. Although calling getCustomTabsSupportingBrowsersAsync breaks ios so had to add platform select
Likewise, fine on iOS Expo Go, but the emulator goes nuts.