I'm using flutter_inappwebview: 6.0.0-beta.22
package and I'm opening the Stripe onboarding process in an in-app web view.
While on Android emulator works as expected and the page is loaded, when I launch the web view on the web app(launched in release mode run -d chrome --release --web-hostname localhost --web-port 5000
) the page doesn't load and on console I get the message
url is: https://connect.stripe.com/setup/c/acct_1MFXNcFwHPwkSrfO/jug2SEGbwzAq
NoSuchMethodError: method not found: 'toString' on null
js_primitives.dart:47 at a6J.aA (http://localhost:5000/main.dart.js?version=9:56217:6)
js_primitives.dart:47 at fY.Gq (http://localhost:5000/main.dart.js?version=9:82446:12)
js_primitives.dart:47 at fY.e0 (http://localhost:5000/main.dart.js?version=9:82409:6)
js_primitives.dart:47 at IQ.Cc (http://localhost:5000/main.dart.js?version=9:82306:3)
js_primitives.dart:47 at IQ.eK (http://localhost:5000/main.dart.js?version=9:82255:16)
js_primitives.dart:47 at IQ.e0 (http://localhost:5000/main.dart.js?version=9:82634:8)
js_primitives.dart:47 at Ai.Cc (http://localhost:5000/main.dart.js?version=9:82306:3)
js_primitives.dart:47 at Ai.eK (http://localhost:5000/main.dart.js?version=9:82255:16)
js_primitives.dart:47 at Ai.kE (http://localhost:5000/main.dart.js?version=9:82417:32)
js_primitives.dart:47 at Ai.wy (http://localhost:5000/main.dart.js?version=9:82382:6)
when clicking on any of the js_primitives.dart:47
links on the right it shows this error
Could not load content for org-dartlang-sdk:///lib/_internal/js_runtime/lib/js_primitives.dart (Fetch through target failed: Unsupported URL scheme; Fallback: HTTP error: status code 404, net::ERR_UNKNOWN_URL_SCHEME)
Now, the url print is from the screen initState and is correct. This is the Screen:
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:universal_platform/universal_platform.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../utilities.dart';
class StripeOnboardScreen extends StatefulWidget {
final String onboardUrl;
const StripeOnboardScreen({Key? key, required this.onboardUrl})
: super(key: key);
@override
State<StripeOnboardScreen> createState() => _StripeOnboardScreenState();
}
class _StripeOnboardScreenState extends State<StripeOnboardScreen> {
dynamic backButton = UniversalPlatform.isWeb
? UniversalPlatform.isIOS
? CupertinoIcons.back
: Icons.arrow_back
: Icons.arrow_back;
double fontSize = Utilities.fontSize;
final GlobalKey webViewKey = GlobalKey();
InAppWebViewController? webViewController;
InAppWebViewSettings settings = InAppWebViewSettings(
javaScriptEnabled: true,
javaScriptCanOpenWindowsAutomatically: true,
useShouldOverrideUrlLoading: true,
mediaPlaybackRequiresUserGesture: false,
allowsInlineMediaPlayback: true,
iframeAllow: "camera; microphone",
iframeAllowFullscreen: true);
late PullToRefreshController pullToRefreshController;
double progress = 0;
// Create a webview controller to control the webview and get information
// about its current state
final urlController = TextEditingController();
@override
void initState() {
super.initState();
print('url is: ${widget.onboardUrl}');
pullToRefreshController = (kIsWeb
? null
: PullToRefreshController(
settings: PullToRefreshSettings(
color: Colors.blue,
),
))!;
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
// Show a "Back" button in the app bar if the webview is displaying
// a page other than the initial page
leading: IconButton(
icon: Icon(backButton),
color: Colors.redAccent,
onPressed: () {
Navigator.pop(context);
}),
),
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: InAppWebView(
key: webViewKey,
initialUrlRequest: URLRequest(
url: WebUri(widget.onboardUrl, forceToStringRawValue: true)),
initialSettings: settings,
pullToRefreshController: pullToRefreshController,
onWebViewCreated: (controller) {
webViewController = controller;
},
onLoadStart: (controller, url) {
setState(() {
urlController.text = widget.onboardUrl;
});
},
onPermissionRequest: (controller, request) async {
return PermissionResponse(
resources: request.resources,
action: PermissionResponseAction.GRANT);
},
shouldOverrideUrlLoading: (controller, navigationAction) async {
var uri = navigationAction.request.url!;
if (![
"http",
"https",
"file",
"chrome",
"data",
"javascript",
"about"
].contains(uri.scheme)) {
await canLaunchUrlString(widget.onboardUrl)
? await launchUrlString(widget.onboardUrl)
: throw 'Could not launch ${widget.onboardUrl}';
// and cancel the request
return NavigationActionPolicy.CANCEL;
}
return NavigationActionPolicy.ALLOW;
},
onConsoleMessage: (controller, consoleMessage) {
print('consoleMessage is : $consoleMessage');
},
),
),
);
}
}
I added the script in the head
as per docs but here is the index.html so you can have look at it
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>fixit</title>
<!-- <meta name="google-signin-client_id" content="YOUR_GOOGLE_SIGN_IN_OAUTH_CLIENT_ID.apps.googleusercontent.com">-->
<meta name="google-signin-client_id"
content="147151203258-clupo1g18oueig38uq8nts5mnkgug13e.apps.googleusercontent.com">
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">-->
<script type="application/javascript" src="/assets/packages/flutter_inappwebview/assets/web/web_support.js" defer></script>
</head>
<!--<body>-->
<body id="app-container">
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-app.js"></script>
<!-- TODO: Add SDKs for Firebase products that you want to use
https://firebase.google.com/docs/web/setup#available-libraries -->
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-analytics.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-messaging.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-storage.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-remote-config.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "xx",
authDomain: "xx",
databaseURL: "xx",
projectId: "xx",
storageBucket: "xx",
messagingSenderId: "xx",
appId: "xx",
measurementId: "xx"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
<!-- firebase.analytics();-->
</script>
<script>
if ("serviceWorker" in navigator) {
window.addEventListener("load", function () {
//navigator.serviceWorker.register("/flutter_service_worker.js");
navigator.serviceWorker.register("/firebase-messaging-sw.js");
});
}
</script>
<script src="main.dart.js?version=9" type="application/javascript"></script>
</body>
</html>
Can you spot what I'm doing wrong?
this is my flutter doctor
[✓] Flutter (Channel stable, 3.3.9, on macOS 12.5.1 21G83 darwin-arm, locale en-IT)
• Flutter version 3.3.9 on channel stable at /Users/vincenzocalia/development/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision b8f7f1f986 (3 weeks ago), 2022-11-23 06:43:51 +0900
• Engine revision 8f2221fbef
• Dart version 2.18.5
• DevTools version 2.15.0
[✓] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
• Android SDK at /Users/vincenzocalia/Library/Android/sdk
• Platform android-33, build-tools 32.1.0-rc1
• Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 13.4.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 13F100
• CocoaPods version 1.11.3
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2021.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
[✓] VS Code (version 1.73.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension can be installed from:
🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (3 available)
• sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64 • Android 12 (API 31) (emulator)
• macOS (desktop) • macos • darwin-arm64 • macOS 12.5.1 21G83 darwin-arm
• Chrome (web) • chrome • web-javascript • Google Chrome 108.0.5359.124
HTTP Host availability check is taking a long time...[✓] HTTP Host Availability
• All required HTTP hosts are available
• No issues found!
Afters stripping down the Screen to the bare minimum (So no InAppWebViewController, PullToRefreshController, no callbacks) it finally displays the link.
Unfortunately Stripe doesn't allow it to be in a iFrame so I get the web an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'
.
So unless there is some settings to put in place for the plugin, I have to open it a new window for the app running on the web..