I’m developing a Flutter app where I need to display multiple instances of a web app (WhatsApp Web) using the flutter_inappwebview package. The goal is to have each instance use separate web storage so that different accounts can stay logged in simultaneously.
Here is a simplified version of my current code:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class Webview extends StatefulWidget {
const Webview({super.key});
@override
_WebviewState createState() => _WebviewState();
}
class _WebviewState extends State<Webview> with WidgetsBindingObserver {
final GlobalKey webViewKey = GlobalKey();
double progress = 0;
InAppWebViewController? webViewController;
InAppWebViewSettings settings = InAppWebViewSettings(
supportMultipleWindows: true,
javaScriptCanOpenWindowsAutomatically: true,
isInspectable: kDebugMode,
mediaPlaybackRequiresUserGesture: false,
allowsInlineMediaPlayback: true,
iframeAllow: "camera; microphone",
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36",
iframeAllowFullscreen: true,
);
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
webViewController = null;
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
int? window;
@override
Widget build(BuildContext context) {
if (kDebugMode) {
print("from webview $window");
}
return Scaffold(
appBar: AppBar(
title: const Text('WhatsApp Login'),
backgroundColor: Colors.black26,
),
body: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ElevatedButton(
onPressed: () => _loadWhatsApp(storagePath: 'account1'),
child: Text('Login with Account 1'),
),
ElevatedButton(
onPressed: () => _loadWhatsApp(storagePath: 'account2'),
child: Text('Login with Account 2'),
),
],
),
Expanded(
child: Stack(
children: [
InAppWebView(
windowId: window,
key: webViewKey,
initialSettings: settings,
onWebViewCreated: (controller) async {
webViewController = controller;
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
await controller.startSafeBrowsing();
}
},
onCreateWindow: (controller, createWindowAction) async {
setState(() {
window = createWindowAction.windowId;
});
print("New window: $window");
InAppWebViewSettings(
supportMultipleWindows: true,
javaScriptCanOpenWindowsAutomatically: true,
);
return true;
},
onCloseWindow: (controller) {},
onProgressChanged: (controller, progress) {
setState(() {
this.progress = progress / 100;
});
},
onConsoleMessage: (controller, consoleMessage) {
if (kDebugMode) {
print(consoleMessage);
}
},
),
progress < 1.0 ? LinearProgressIndicator(value: progress) : Container(),
],
),
),
],
),
);
}
Future<void> _loadWhatsApp({required String storagePath}) async {
if (webViewController != null) {
await InAppWebViewController.clearAllCache();
await InAppWebViewController.clearClientCertPreferences();
Directory appDocDir = await getApplicationDocumentsDirectory();
String fullStoragePath = '${appDocDir.path}/$storagePath';
await Directory(fullStoragePath).create(recursive: true);
InAppWebViewSettings newSettings = InAppWebViewSettings(
cacheEnabled: true,
databaseEnabled: true,
domStorageEnabled: true,
useShouldInterceptRequest: true,
useOnLoadResource: true,
useOnDownloadStart: true,
allowUniversalAccessFromFileURLs: true,
allowFileAccessFromFileURLs: true,
applicationCachePath: fullStoragePath,
);
await webViewController!.setSettings(settings: newSettings);
await webViewController!.loadUrl(
urlRequest: URLRequest(
url: WebUri("https://web.whatsapp.com/"),
),
);
}
}
}
The Issue:
Despite my efforts, logging into one account causes the other account to log out. This indicates that the sessions are not truly separate, and the web storage is still being shared between the two web views.
My Attempts:
1.Tried clearing the cache and client certificate preferences before loading the URL.
2.Set different application cache paths for each session.
Question:
How can I properly configure flutter_inappwebview to maintain separate web storage for multiple sessions? Is there a specific way to set different storage paths or any other settings that I might be missing?
Any help or suggestions on this would be greatly appreciated!
pavan kalyan reddy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.