detect-provider
detect-provider copied to clipboard
@metamask/detect-provider: Unable to detect window.ethereum.
I'm building a hybrid app using Ionic.
When I serve the app in the browser (Chrome), it works fine asking for the Metamask authentication (opens Metamask as expected).
However when I build that for native Android (I'm using Capacitor), even though the app opens on my Android phone normally after I launch it from Android Studio, it does not ask me to authenticate with Metamask.
After doing some troubleshoot I attached to the app (via Chrome Device Inspect) running on my real phone which is plugged via USB in my computer, and this is what I get on the native app:
common.js:166 @metamask/detect-provider: Unable to detect window.ethereum.
handleEthereum @ common.js:166
23:50:21.508 vendor.js:86490 ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of null (reading 'request')
TypeError: Cannot read properties of null (reading 'request')
at src_app_home_home_module_ts.js:272:22
at ZoneDelegate.invoke (polyfills.js:413:30)
at Object.onInvoke (vendor.js:108502:25)
at ZoneDelegate.invoke (polyfills.js:412:56)
at Zone.run (polyfills.js:173:47)
at polyfills.js:1331:38
at ZoneDelegate.invokeTask (polyfills.js:447:35)
at Object.onInvokeTask (vendor.js:108490:25)
at ZoneDelegate.invokeTask (polyfills.js:446:64)
at Zone.runTask (polyfills.js:218:51)
at resolvePromise (polyfills.js:1268:35)
at polyfills.js:1338:21
at ZoneDelegate.invokeTask (polyfills.js:447:35)
at Object.onInvokeTask (vendor.js:108490:25)
at ZoneDelegate.invokeTask (polyfills.js:446:64)
at Zone.runTask (polyfills.js:218:51)
at drainMicroTaskQueue (polyfills.js:633:39)
at ZoneTask.invokeTask (polyfills.js:533:25)
at ZoneTask.invoke (polyfills.js:518:52)
at data.args.<computed> (polyfills.js:3076:36)
What should I do in order to have the native app being able to authenticate with the Metamask installed app?
Thanks!
I'm getting this in the web app in Chrome, Even a basic example from docs throws this error. I tried to run it on http or https, no difference.
DeoThemes
Did you figure this out at all? I am getting the same thing. Production web app served over https. Works fine in the browser on desktop, but doesn't find the metaMask app on iOS or Android.
Unfortunately I didn't manage to solve the problem.
@caio1985 @stramec Are you accessing your app within the MetaMask browser on mobile or outside the app?
@caio1985 @stramec Are you accessing your app within the MetaMask browser on mobile or outside the app?
Perhaps I have misunderstood how this works, but one testing scenario is we have our web app open in say iOS chrome. The test mobile has the metamask app installed. From the docs it states "We recommend using @metamask/detect-provider (opens new window)to detect our provider, on any platform or browser." so I assumed it would therefore realise the metamask Apple app is installed and continue from there.
It works fine with the browser extension installed on the desktop. Have I assumed incorrectly on the mobile app side?
@stramec
I think the docs could be more helpful here, but mobile doesn't work like you may think.
On the desktop side, you will install the MetaMask extension in your browser. The extension provides a UI for you to use MetaMask, which you know, but it also injects a script into every single page that you visit (with some exceptions). It's this injected script that makes it possible for a dapp to interact with the extension via window.ethereum. All the detect-provider library does is look for the presence of this property on window (as well as window.ethereum.isMetaMask, which we set to distinguish ourselves, in case other browser extensions also set window.ethereum).
Mobile is different because we don't provide MetaMask through a browser extension, we offer a separate app. Apps can't talk directly to each other, so if you have a dapp open in iOS Chrome, iOS Safari, Android Chrome, Android Firefox, etc., the site can't know that you have MetaMask installed, because no such script is injected on the page like it is in the browser on desktop. So does this mean that it's impossible for a dapp running on mobile to detect MetaMask? No, because MetaMask-the-app has a browser built into it, and this browser injects a script onto every page that's visited. That means that in order to provide the experience you want, you need users to visit the dapp from within MetaMask, not outside of it. To help with user experience, you may want to update the code in your dapp such that if detect-provider can't detect the presence of window.ethereum, you can assume that the user isn't within MetaMask and show a deeplink that (re)opens your dapp within MetaMask instead. We have a deeplink generator you can use here: https://metamask.github.io/metamask-deeplinks.
I hope that helps!
Perfect answer, cheers @mcmire - all makes sense now.