Flutter get logged user data to other screen view - dart

I have API.dart like this to authenticating a user, log in and log out
class Api {
static FirebaseAuth _auth = FirebaseAuth.instance;
static GoogleSignIn _googleSignIn = GoogleSignIn();
FirebaseUser firebaseUser;
Api(FirebaseUser user) {
this.firebaseUser = user;
}
static Future<FBApi> signInWithGoogle() async {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final FirebaseUser user = await _auth.signInWithGoogle(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
assert(user.email != null);
assert(user.displayName != null);
assert(await user.getIdToken() != null);
final FirebaseUser currentUser = await _auth.currentUser();
assert(user.uid == currentUser.uid);
// print('photoURL api ' + user.photoUrl);
return Api(user);
}
static Future<void> signOut() async {
await _auth.signOut().then((_) {
print("***** log out...what the hell?");
_googleSignIn.signOut();
});
}
}
I've have a cloud function to create new user to database cloud firestore.
And in view account settings, I want to update user information like displayName, photoUrl into firestore. How I get current user in my account setting view.
class Settings extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(
'ACCOUNT',
style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
),
centerTitle: true,
),
body: new SettingsScreen(),
);
}
}
class SettingsScreen extends StatefulWidget {
#override
State createState() => new SettingsScreenState();
}
class SettingsScreenState extends State<SettingsScreen> {
TextEditingController controllerNickname;
SharedPreferences prefs;
String id;
String nickName;
String photoUrl;
bool isLoading = false;
File avatarImageFile;
final FocusNode focusNodeNickname = new FocusNode();
#override
void initState() {
super.initState();
readLocal();
}
void readLocal() async {
prefs = await SharedPreferences.getInstance();
id = prefs.getString('id') ?? '';
nickName = prefs.getString('nickName') ?? '';
photoUrl = prefs.getString('photoUrl') ?? '';
controllerNickname = new TextEditingController(text: nickName);
// Force refresh input
setState(() {});
}
Future getImage() async {
File image = await ImagePicker.pickImage(source: ImageSource.gallery);
if (image != null) {
setState(() {
avatarImageFile = image;
isLoading = true;
});
}
uploadFile();
}
Future uploadFile() async {
String fileName = id;
StorageReference reference = FirebaseStorage.instance.ref().child(fileName);
StorageUploadTask uploadTask = reference.putFile(avatarImageFile);
StorageTaskSnapshot storageTaskSnapshot;
uploadTask.onComplete.then((value) {
if (value.error == null) {
storageTaskSnapshot = value;
storageTaskSnapshot.ref.getDownloadURL().then((downloadUrl) {
photoUrl = downloadUrl;
Firestore.instance
.collection('users')
.document(id)
.updateData({'displayName': nickName, 'photoUrl': photoUrl}).then((data) async {
await prefs.setString('photoUrl', photoUrl);
setState(() {
isLoading = false;
});
Fluttertoast.showToast(msg: "Upload success");
}).catchError((err) {
setState(() {
isLoading = false;
});
Fluttertoast.showToast(msg: err.toString());
});
}, onError: (err) {
setState(() {
isLoading = false;
});
Fluttertoast.showToast(msg: 'This file is not an image');
});
} else {
setState(() {
isLoading = false;
});
Fluttertoast.showToast(msg: 'This file is not an image');
}
}, onError: (err) {
setState(() {
isLoading = false;
});
Fluttertoast.showToast(msg: err.toString());
});
}
void handleUpdateData() {
focusNodeNickname.unfocus();
setState(() {
isLoading = true;
});
Firestore.instance
.collection('users')
.document(id)
.updateData({'displayName': nickName, 'photoUrl': photoUrl}).then((data) async {
await prefs.setString('nickname', nickName);
await prefs.setString('photoUrl', photoUrl);
setState(() {
isLoading = false;
});
Fluttertoast.showToast(msg: "Update success");
}).catchError((err) {
setState(() {
isLoading = false;
});
Fluttertoast.showToast(msg: err.toString());
});
}
#override
Widget build(BuildContext context) {
...

You can do something like this FirebaseAuth.instance.currentUser()
This returns the current user if any. Otherwise it returns null

Related

flutter provider: notifyListeners(); is not working after changing variable still showing null on printing

the problem is when i try to log in the user user name should show up instead of null the signName variable should hold the username from firebase cloud when i try to the user its showing the correct username from firebase db but when i try to print the value if variable like uid or signName or bool values like loggedin they show the initial value pls help
this is my class that extend change ChangeNotifier
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:indiaghumo/utils.dart';
class FirebaseAuthMethod extends ChangeNotifier {
String? uid;
String? signName;
String? guest;
bool loggedin = false;
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _firetore = FirebaseFirestore.instance;
// String res = "Failed to login";
// FirebaseAuthMethod(this._auth);
Stream<User?> get authstate => FirebaseAuth.instance.authStateChanges();
User get user => _auth.currentUser!;
Future<void> signUpWithEmail(
{required String email,
required String password,
required String username,
required BuildContext context}) async {
try {
UserCredential cred = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
uid = cred.user!.uid;
loggedin = true;
// print(_auth.currentUser!.email);
try {
_firetore.collection("users").doc(cred.user!.uid).set({
"username": username,
"uid": cred.user!.uid,
"email": email,
});
getdata(uid!);
// notifyListeners();
} on FirebaseException catch (e) {
showSnackbar(context, e.message.toString());
}
// await sendEmailVerificaton(context);
} on FirebaseAuthException catch (e) {
showSnackbar(context, e.message.toString());
}
notifyListeners();
}
// Future<void> sendEmailVerificaton(BuildContext context) async {
// try {
// _auth.currentUser!.sendEmailVerification();
// } on FirebaseAuthException catch (e) {
// showSnackbar(context, e.message.toString());
// }
// }
loginWithEmail(
{required String email,
required String password,
required BuildContext context}) async {
try {
UserCredential cred = await _auth.signInWithEmailAndPassword(
email: email, password: password);
uid = cred.user!.uid;
loggedin = true;
getdata(uid!);
// notifyListeners();
// if (!_auth.currentUser!.emailVerified) {
// sendEmailVerificaton(context);
// }
} on FirebaseAuthException catch (e) {
showSnackbar(context, e.message.toString());
}
notifyListeners();
}
Future<void> logOut(BuildContext context) async {
try {
await _auth.signOut();
loggedin = false;
signName = "guest";
} on FirebaseAuthException catch (e) {
showSnackbar(context, e.message.toString());
}
notifyListeners();
}
Future<void> forgetPassword(
{required BuildContext context, required String email}) async {
try {
await _auth.sendPasswordResetEmail(email: email);
} on FirebaseAuthException catch (e) {
showSnackbar(context, e.message.toString());
}
}
getdata(String uID) async {
String? i = await _firetore
.collection("users")
.doc(uID.toString())
.get()
.then((snapshot) {
guest = snapshot.get("username");
signName = guest;
// print(signName);
});
// print(signName);
print(uID);
notifyListeners();
return i;
}
test(String str) {
signName = str;
notifyListeners();
}
}
this is my button where i called my variable from changenotifier class
IconButton(
icon: const Icon(
Icons.notifications_rounded,
color: Colors.white,
),
onPressed: () {
print(context.read<FirebaseAuthMethod>().loggedin);
},
),
the output is : I/flutter (14797): false
even after successful login the value of bool didnt changed
below is my main file
import 'package:flutter/material.dart';
import 'package:indiaghumo/screens/Signup.dart';
import 'package:indiaghumo/screens/forgetpassword.dart';
import 'package:indiaghumo/screens/homescreen.dart';
import 'package:indiaghumo/screens/locationPage.dart';
import 'package:indiaghumo/screens/login.dart';
import 'package:indiaghumo/services/firebase_auth.dart';
import 'package:indiaghumo/services/locationAndCity.dart';
import 'package:provider/provider.dart';
import 'firebase_options.dart';
import 'package:firebase_core/firebase_core.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => FirebaseAuthMethod(),
),
ChangeNotifierProvider(
create: (_) => LocationAndPlace(),
),
],
child: MaterialApp(
home: LocationPage(),
),
);
}
}

Flutter Text To Speech: Speak several strings subsequently with different SpeechRates

I have a problem with the Flutter Text To Speech package.
When clicking on a FloatingActionButton I would like to speak/play several Strings (with different Speechrates) subsequently. However, when doing so, I can only hear the last string that I have passed onto the function and not the first one.
As you can see in the code below, I have tried to make use of the asynchronus programming (async / await).
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter_tts/flutter_tts.dart';
class SpeakerClass extends StatefulWidget{
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _SpeakerClassState();
}
}
class _SpeakerClassState extends State<SpeakerClass>{
String text1 = 'eins';
String text2 = 'zwei';
String text3 = 'drei';
String text4 = 'vier';
String currentTtsString;
double ttsSpeechRate1 = 0.5;
double ttsSpeechRate2 = 1.0;
double currentSpeechRate;
Future playTtsString1() async {
currentTtsString = text1;
currentSpeechRate = ttsSpeechRate1;
await runTextToSpeech(currentTtsString, currentSpeechRate);
return null;
}
Future playTtsString2() async {
currentTtsString = text2;
currentSpeechRate = ttsSpeechRate2;
await runTextToSpeech(currentTtsString, currentSpeechRate);
return null;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FloatingActionButton (
backgroundColor: Colors.blue,
child: Icon(Icons.volume_up, color: Colors.white),
onPressed: () async {
await playTtsString1();
await playTtsString2();
},
)
);
}
}
Future<void> runTextToSpeech(String currentTtsString, double currentSpeechRate) async {
FlutterTts flutterTts;
flutterTts = new FlutterTts();
await flutterTts.setLanguage("en-GB");
await flutterTts.setVolume(1.0);
await flutterTts.setPitch(1.0);
await flutterTts.isLanguageAvailable("en-GB");
await flutterTts.setSpeechRate(currentSpeechRate);
await flutterTts.speak(currentTtsString);
}
When pressing the FloatingActionButton I expect the program to first carry out the function playTtsString1 ("eins" with a speed of 0.5) and afterwards the function playTtsString2 ("zwei" with a speed of 1).
However, somehow I can only hear the program saying "zwei". I guess the program is not waiting for the first function "playTtsString1" to be finished and already carries out the second function "playTtsString2". I would really appreciate any help on this matter!
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter_tts/flutter_tts.dart';
class SpeakerClass extends StatefulWidget{
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _SpeakerClassState();
}
}
class _SpeakerClassState extends State<SpeakerClass>{
String text1 = 'eins';
String text2 = 'zwei';
String text3 = 'drei';
String text4 = 'vier';
String currentTtsString;
double ttsSpeechRate1 = 0.5;
double ttsSpeechRate2 = 1.0;
double currentSpeechRate;
FlutterTts flutterTts;
bool bolSpeaking = false;
Future playTtsString1() async {
bolSpeaking = true;
currentTtsString = text1;
currentSpeechRate = ttsSpeechRate1;
await runTextToSpeech(currentTtsString, currentSpeechRate);
return null;
}
Future playTtsString2() async {
bolSpeaking = true;
currentTtsString = text2;
currentSpeechRate = ttsSpeechRate2;
await runTextToSpeech(currentTtsString, currentSpeechRate);
return null;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FloatingActionButton (
backgroundColor: Colors.blue,
child: Icon(Icons.volume_up, color: Colors.white),
onPressed: () async {
// Play String 1
await playTtsString1();
// Check String 1 Finish
new Future.delayed(new Duration(milliseconds: 100), () async {
// loop until bolSpeaking = false
while (bolSpeaking) {
await Thread.sleep(100);
}
// play String 2
await playTtsString2();
}
},
)
);
}
}
Future<void> runTextToSpeech(String currentTtsString, double currentSpeechRate) async {
flutterTts = new FlutterTts();
await flutterTts.setLanguage("en-GB");
await flutterTts.setVolume(1.0);
await flutterTts.setPitch(1.0);
await flutterTts.isLanguageAvailable("en-GB");
await flutterTts.setSpeechRate(currentSpeechRate);
flutterTts.setCompletionHandler(() {
setState(() {
// The following code(s) will be called when the TTS finishes speaking
bolSpeaking = false;
});
});
flutterTts.speak(currentTtsString);
}
This should now work with the latest flutter_tts version.
You simply need to set awaitSpeakCompletion before the speaking happens.
You can update your run method like so:
Future<void> runTextToSpeech(String currentTtsString, double currentSpeechRate) async {
FlutterTts flutterTts;
flutterTts = new FlutterTts();
await flutterTts.awaitSpeakCompletion(true);
await flutterTts.setLanguage("en-GB");
await flutterTts.setVolume(1.0);
await flutterTts.setPitch(1.0);
await flutterTts.isLanguageAvailable("en-GB");
await flutterTts.setSpeechRate(currentSpeechRate);
await flutterTts.speak(currentTtsString);
}

Flutter dart function skipping to end of function after await

I have a function with the keyword async and after the await is done, it skips a bunch of lines of codes and goes to the end of the function after the await is done. Does anyone know what I am doing wrong?
void _createNewGroup(Function createNewGroup, BuildContext context) async {
if (_validateAndSave()) {
try {
print("trying");
Map<String, dynamic> result = await createNewGroup(_group_name);
print("sucess is $result");
if (result['success']) {
print('Success poping dialoge');
Navigator.of(context).pop();
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => HomePage()));
} else {
print("not created group");
}
} catch (error) {}
}
}
Future<Map<String, dynamic>> createNewGroup(String name) async {
var result = {};
var response;
print('Group name $name');
print("creating group");
var group = ParseObject('Groups')
..set("group_name", name)
..set('createdBy_name', _parseUser.get('first_name'))
..set('CreatedBy_id', _parseUser.objectId)
..set('members', [{'name': _parseUser.get('first_name'), 'id': _parseUser.objectId}]);
response = await group.save();
if(response.success) {
print('sucess creating object');
result = {'success': true, 'message': 'New Group Created'};
return result;
} else {
result = {'success': false, 'message': 'Error occured creating group'};
}
print("result is $result");
print("response is ${response.result}");
return result;
}

How to clear data in bloc?

As is it right now, when a user tries to click login, the button changes to a progress bar. The trouble i'm having is that I'm not able to get the progress bar turned back into a button using streams.
I'm kinda copying a tutorial I found online and I'm trying to modify it to fit what I need so I'm not 100% understanding bloc yet.
This is the tutorial I'm kinda following
https://medium.com/flutterpub/when-firebase-meets-bloc-pattern-fb5c405597e0
This is the login button
Widget loginButton() {
return StreamBuilder(
stream: _bloc.signInStatus,
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData || snapshot.hasError) {
return button();
} else {
return LinearProgressIndicator();
}
});
}
Widget button() {
return Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: MaterialButton(
minWidth: 200.0,
height: 42.0,
child: Text(
StringConstant.submit,
style: TextStyle(color: Colors.white),
),
color: ThemeSettings.RaisedButton,
onPressed: () {
if (_bloc.validateFields()) {
authenticateUser();
} else {
showAlertDialog(context, "Verification Failed",
"The Email / Number you entered couldn't be found or your password was incorrect. Please try again.");
}),
);
}
void authenticateUser() {
_bloc.showProgressBar(true);
_bloc.authenticateUser().then((value) {
//Username and password ARE correct
if (value) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => EventsList(_bloc.emailAddress)));
} else {
print("this one");
showAlertDialog(context, "Verification Failed",
"The Email / Number you entered couldn't be found or your password was incorrect. Please try again.");
// I believe I need to clear what is inside of snapshot here?
}
});
}
and inside of my login_bloc.dart here is what I think is important to know?
class LoginBloc {
final _repository = Repository();
final _email = BehaviorSubject<String>();
final _password = BehaviorSubject<String>();
final _firstName = BehaviorSubject<String>();
final _phoneNumber = BehaviorSubject<int>();
final _profilePicture = BehaviorSubject<String>();
final _isSignedIn = BehaviorSubject<bool>();
Observable<String> get email => _email.stream.transform(_validateEmail);
Observable<String> get password =>
_password.stream.transform(_validatePassword);
Observable<bool> get signInStatus => _isSignedIn.stream;
String get emailAddress => _email.value;
// Change data
Function(String) get changeEmail => _email.sink.add;
Function(String) get changePassword => _password.sink.add;
Function(bool) get showProgressBar => _isSignedIn.sink.add;
final _validateEmail =
StreamTransformer<String, String>.fromHandlers(handleData: (email, sink) {
if (email.contains('#')) {
sink.add(email);
} else {
sink.addError(StringConstant.emailValidateMessage);
}
});
final _validatePassword = StreamTransformer<String, String>.fromHandlers(
handleData: (password, sink) {
if (password.length >= 6) {
sink.add(password);
} else {
sink.addError(StringConstant.passwordValidateMessage);
}
});
Future<bool> authenticateUser() {
return _repository.authenticateUser(_email.value, _password.value);
}
Future<AuthenticatedStatus> doesUserExist() {
return _repository.doesUserExist(_email.value);
}
Future<void> addUserToDatabase() {
return _repository.addUserToDatabase(_email.value, _password.value,
_firstName.value, _phoneNumber.value, _profilePicture.value);
}
bool validateFields() {
if (_email.value != null &&
_email.value.isNotEmpty &&
_password.value != null &&
_password.value.isNotEmpty &&
_email.value.contains('#') &&
_password.value.length >= 6) {
return true;
} else {
return false;
}
}
void dispose() async {
await _email.drain();
_email.close();
await _password.drain();
_password.close();
await _firstName.drain();
_firstName.close();
await _phoneNumber.drain();
_phoneNumber.close();
await _profilePicture.drain();
_profilePicture.close();
await _isSignedIn.drain();
_isSignedIn.close();
}
I have yet to try the sample provided in the blog post, but going through the snippets, it looks like a simple _bloc.showProgressBar(false); should do the trick. Have you tried doing so?

How to render a local HTML file with flutter dart webview

I want to render a local HTML file stored in my phone memory in webview using flutter and dart.
I am using the webview_flutter plugin from the Flutter Team.
Steps
Add the dependency to pubspec.yaml:
dependencies:
webview_flutter: ^0.3.20+2
Put an html file in the assets folder (see this). I'll call it help.html.
Get the html string in code and add it to the webview.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
class HelpScreen extends StatefulWidget {
#override
HelpScreenState createState() {
return HelpScreenState();
}
}
class HelpScreenState extends State<HelpScreen> {
WebViewController _controller;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Help')),
body: WebView(
initialUrl: 'about:blank',
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
_loadHtmlFromAssets();
},
),
);
}
_loadHtmlFromAssets() async {
String fileText = await rootBundle.loadString('assets/help.html');
_controller.loadUrl( Uri.dataFromString(
fileText,
mimeType: 'text/html',
encoding: Encoding.getByName('utf-8')
).toString());
}
}
Notes:
I needed to set the encoding to UTF-8 because I was getting a crash for non-ASCII characters.
In iOS you need to add the key io.flutter.embedded_views_preview as true in the Info.plist file. Check the docs for any update on this requirement.
See also
The Power of WebViews in Flutter
You can pass a data URI
Uri.dataFromString('<html><body>hello world</body></html>', mimeType: 'text/html').toString()
or you can launch a web server inside Flutter and pass an URL that points to the IP/port the server serves the file from.
See also the discussion in https://github.com/fluttercommunity/flutter_webview_plugin/issues/23
See https://flutter.io/docs/development/ui/assets-and-images#loading-text-assets about how to load a string from assets.
See https://flutter.io/docs/cookbook/persistence/reading-writing-files for how to read other files.
#Suragch, your code doesn't work as you posted it, it says localUrl was called on null.
_loadHtmlFromAssets needs to be called after assigning the controller :
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
_loadHtmlFromAssets();
}
Then it works fine :)
You may use Flutter InAppWebView Plugin. It will create a local server inside the app and it’ll run the HTML app there in the WebView. Start your server:
InAppLocalhostServer localhostServer = new InAppLocalhostServer();
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await localhostServer.start();
runApp(new MyApp());
}
//... ...
class _MyHomePageState extends State < MyHomePage > {
//... ...
#override
void dispose() {
localhostServer.close();
super.dispose();
}
}
And then point your localhost html index file in the WebView.
InAppWebView(
initialUrlRequest: URLRequest(
url: Uri.parse('http://localhost:8080/assets/index.html')),
),
In many cases it doesn't work for many people because they forget to add all the folders as the assets in the pubspec.yaml file. For example, you need to specify all the folders and index file like below:
assets:
- assets/index.html
- assets/css/
- assets/images/
- assets/js/
- assets/others/
You can see this tutorial for further details.
I have the same problem; this is how I solved it.
Add webview_flutter to your project dependencies:
webview_flutter: 0.3.14+1
Create a WebViewController inside your screen/stateful widget
WebViewController _controller;
Implement the WebView and assign a value to the _controller using the onWebViewCreated property. Load the HTML file.
WebView(
initialUrl: '',
onWebViewCreated: (WebViewController webViewController) async {
_controller = webViewController;
await loadHtmlFromAssets('legal/privacy_policy.html', _controller);
},
)
Implement the function to load the file from the asset folder
Future<void> loadHtmlFromAssets(String filename, controller) async {
String fileText = await rootBundle.loadString(filename);
controller.loadUrl(Uri.dataFromString(fileText, mimeType: 'text/html', encoding: Encoding.getByName('utf-8')).toString());
}
You can use my plugin flutter_inappwebview, which has a lot of events, methods, and options compared to other plugins!
To load an html file from your assets folder, you need to declare it in the pubspec.yaml file before use it (see more here).
Example of a pubspec.yaml file:
...
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
assets:
- assets/index.html
...
After that, you can simply use the initialFile parameter of the InAppWebView widget to load index.html into the WebView:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: InAppWebViewPage()
);
}
}
class InAppWebViewPage extends StatefulWidget {
#override
_InAppWebViewPageState createState() => new _InAppWebViewPageState();
}
class _InAppWebViewPageState extends State<InAppWebViewPage> {
InAppWebViewController webView;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("InAppWebView")
),
body: Container(
child: Column(children: <Widget>[
Expanded(
child: Container(
child: InAppWebView(
initialFile: "assets/index.html",
initialHeaders: {},
initialOptions: InAppWebViewWidgetOptions(
inAppWebViewOptions: InAppWebViewOptions(
debuggingEnabled: true,
),
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
},
onLoadStart: (InAppWebViewController controller, String url) {
},
onLoadStop: (InAppWebViewController controller, String url) {
},
),
),
),
]))
);
}
}
unzip the apk package,I found the reason: path is wrong;
For Android:
"assets/test.html" == "file:///android_asset/flutter_assets/assets/test.html"
so,just like this:
WebView(
initialUrl: "file:///android_asset/flutter_assets/assets/test.html",
javascriptMode: JavascriptMode.unrestricted,
)
you can load "assets/test.html".
The asset_webview plugin is specifically designed for this. Fewer features than other plugins, but simple to use.
Use flutter_widget_from_html_core---->
link -> https://pub.dev/packages/flutter_widget_from_html_core
dependencies:
flutter_widget_from_html_core: ^0.5.1+4
Code like this
HtmlWidget(
"""
<html lang="en">
<body>hello world</body>
</html>
""",
),
Finally found a proper way
String webview_content = '''
<!DOCTYPE html>
<html lang="en">
<head>
<title>Load file or HTML string example</title>
</head>
<body>
<h1>Local demo page</h1>
<p>
This is an example page used to demonstrate how to load a local file
or
HTML
string using the <a
href="https://pub.dev/packages/webview_flutter">Flutter
webview</a> plugin.
</p>
</body>
</html>
''';
final Completer<WebViewController> _controller =
Completer<WebViewController>();
Future<void> _loadHtmlString(
Completer<WebViewController> controller, BuildContext context) async {
WebViewController _controller = await controller.future;
await _controller.loadHtmlString(webview_content);
return WebView(
initialUrl: 'https://flutter.dev',
onWebViewCreated:
(WebViewController webViewController) async {
_controller.complete(webViewController);
_loadHtmlString(_controller, context);
},
),
I follow #Suragch answer and find that local image path in the html file cannot be loaded. So I tried a few ways and found that replacing the method loadUrl() with loadFlutterAsset() actually do the job (the code is also more simple).
class UserGuidePage extends StatefulWidget {
final UserGuideArguments arguments;
const UserGuidePage({required this.arguments, Key? key}) : super(key: key);
#override
State<UserGuidePage> createState() => _UserGuidePageState();
}
class _UserGuidePageState extends State<UserGuidePage> {
late WebViewController _controller;
#override
Widget build(BuildContext context) {
return WebView(
initialUrl: 'about:blank',
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
_loadHtmlFromAssets();
},
);
}
void _loadHtmlFromAssets() {
_controller.loadFlutterAsset('assets/index.html');
}
}
You can get the page html and use it to load the page with code below that is an example
import 'dart:convert';
import 'package:aws_bot/Utils/Const.dart';
import 'package:aws_bot/Utils/User.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:html/parser.dart';
class signIn extends StatefulWidget {
const signIn({Key? key}) : super(key: key);
#override
_signInState createState() => _signInState();
}
class _signInState extends State<signIn> {
String userEmail = "";
String userPassword = "";
final flutterWebviewPlugin = new FlutterWebviewPlugin();
bool evalJsOnce = false;
String _currentUrl = "";
User _user = User();
bool _loading = true;
double progress = 0.0;
#override
void initState() {
super.initState();
// Future.delayed(Duration(microseconds: 3), () async {
// Map info = await _user.getEmailPassword();
// _user.userEmail = info['email'];
// _user.userPassword = info['password'];
// setState(() {});
// });
}
#override
Widget build(BuildContext context) {
flutterWebviewPlugin.onProgressChanged.listen((double progress) {
print("progress changed = $progress");
if (progress == 1.0) {
//https://portal.aws.amazon.com/billing/signup
flutterWebviewPlugin.onUrlChanged.listen((String url) {
_currentUrl = url;
print("url changed = $url");
if (url.contains('https://portal.aws.amazon.com/billing/signup')) {
print("signup");
flutterWebviewPlugin.evalJavascript(''
'document.querySelector("#CredentialCollection").addEventListener("submit", function(e) {window.Mchannel.postMessage(JSON.stringify({"email": document.querySelector("#awsui-input-0").value, "password": document.querySelector("#awsui-input-1").value, "confirmPass": document.querySelector("#awsui-input-2").value, "accountName": document.querySelector("#awsui-input-3").value}));});');
} else {
flutterWebviewPlugin.evalJavascript(''
'let pageHtml = document.documentElement.innerHTML;'
'window.Emailchannel.postMessage(pageHtml);'
'if (pageHtml.includes("Root user email address")) {'
'document.querySelector("#next_button").addEventListener("click", function(e) {window.Emailchannel.postMessage(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});}'
'');
}
// } else if (url.contains(
// 'https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3Ffromtb%3Dtrue%26hashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-east-1_2b2a9061808657b8&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&forceMobileApp=0&code_challenge=-HEkj8kWzXDv2qBLcBQX2GYULvcP2gsHr0p0X_fJJcU&code_challenge_method=SHA-256')) {
// flutterWebviewPlugin.evalJavascript(''
// 'document.querySelector("#next_button").addEventListener("click", function(e) {e.preventDefault(); window.Emailchannel.postMessage(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});;');
// } else if (url.contains(
// "https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3Ffromtb%3Dtrue%26hashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-east-1_c885b81ed0514ab4&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&forceMobileApp=0&code_challenge=_Tqr3pEXTDAqOYjWp0ehE6ToYYSN7OLeyJWBx5HTPVM&code_challenge_method=SHA-256")) {
// print("enter pass");
// // flutterWebviewPlugin.evalJavascript(''
// // 'document.querySelector("#signin_button").addEventListener("click", function(e) {e.preventDefault(); window.Passwordchannel.postMessage(JSON.stringify({"password": document.querySelector("#password").value}));});;');
// } else if (url.contains("https://console.aws.amazon.com/")) {
// // flutterWebviewPlugin.launch(_consts.successDirectUrl +
// // "email=${_user.userEmail}&password=${_user.userPassword}");
// }
});
}
});
flutterWebviewPlugin.onStateChanged.listen((WebViewStateChanged state) {
print("state changed = $state");
});
return Scaffold(
appBar: AppBar(
title: Text(
'AWS Sign In',
style: TextStyle(color: Colors.black),
),
backgroundColor: Colors.yellow[600],
),
floatingActionButton: _backButton(context),
body: Column(
children: [
(progress != 1.0)
? LinearProgressIndicator(
// minHeight: 10.0,
value: progress,
backgroundColor: Colors.redAccent,
valueColor: AlwaysStoppedAnimation<Color>(Colors.black))
: Container(),
Container(
color: Colors.yellow[600],
width: double.infinity,
padding: EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Email Address of you AWS : ${consts.user.userEmail}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
SizedBox(
height: 4.0,
),
Text(
"IAM user name : ${consts.user.accountName}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
SizedBox(
height: 4.0,
),
Text(
"Password : ${consts.user.userPassword != "null" && consts.user.userPassword != "" ? consts.user.userPassword.replaceAll(consts.user.userPassword, "******") : ""}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
],
)),
Expanded(child: _buildSignInPage()),
],
),
);
}
_buildSignInPage() {
String _url = "https://console.aws.amazon.com/iam/home#/users";
return InAppWebView(
initialUrlRequest: URLRequest(url: Uri.parse(_url)),
// javascriptChannels: Set.from([
// JavascriptChannel(
// name: 'Emailchannel',
// onMessageReceived: (JavascriptMessage message) {
// //This is where you receive message from
// //javascript code and handle in Flutter/Dart
// //like here, the message is just being printed
// //in Run/LogCat window of android studio
// print("console message = ${message.message}");
// setState(() {
// _user.userEmail =
// jsonDecode(message.message)['email'].toString();
// });
// }),
// JavascriptChannel(
// name: 'Passwordchannel',
// onMessageReceived: (JavascriptMessage message) {
// //This is where you receive message from
// //javascript code and handle in Flutter/Dart
// //like here, the message is just being printed
// //in Run/LogCat window of android studio
// print("console message = ${jsonDecode(message.message)}");
// setState(() {
// _user.userEmail =
// jsonDecode(message.message)['password'].toString();
// });
// })
// ]),
// withJavascript: true,
onConsoleMessage: (controller, consoleMessage) async {
print("console message = ${consoleMessage.message}");
print(consoleMessage.messageLevel.toString());
// LOG ERROR => message levels
if (consoleMessage.messageLevel.toString() != "ERROR" &&
consoleMessage.messageLevel.toString() != "WARNING") {
Map message = jsonDecode(consoleMessage.message);
if (message.containsKey("email")) {
consts.user.userEmail = message['email'].toString();
await consts.user.storeSignUpInfo(email: consts.user.userEmail);
} else if (message.containsKey("password")) {
consts.user.userPassword = message['password'].toString();
await consts.user
.storeSignUpInfo(password: consts.user.userPassword);
} else if (message.containsKey("delete")) {
Future.delayed(Duration.zero, () async {
await consts.user.clearStorage();
consts.user.userEmail = "";
consts.user.userPassword = "";
});
} else if (message.containsKey("sEmail")) {
consts.user.userEmail = message['sEmail'].toString();
await consts.user.storeSignUpInfo(email: consts.user.userEmail);
} else if (message.containsKey("sPassword")) {
consts.user.userPassword = message["sPassword"].toString();
await consts.user
.storeSignUpInfo(password: consts.user.userPassword);
} else if (message.containsKey("sAccountName")) {
consts.user.accountName = message["sAccountName"].toString();
await consts.user
.storeSignUpInfo(accountName: consts.user.accountName);
} else if (message.containsKey("sFullName")) {
consts.user.fullName = message["sFullName"].toString();
await consts.user.storeSignUpInfo(fullName: consts.user.fullName);
} else if (message.containsKey("sPhone")) {
consts.user.phoneNumber = message["sPhone"].toString();
await consts.user
.storeSignUpInfo(phoneNumber: consts.user.phoneNumber);
} else if (message.containsKey("sRegion")) {
consts.user.region = message["sRegion"].toString();
await consts.user.storeSignUpInfo(region: consts.user.region);
} else if (message.containsKey("sAddress")) {
consts.user.address = message["sAddress"].toString();
await consts.user.storeSignUpInfo(address: consts.user.address);
} else if (message.containsKey("sCity")) {
consts.user.city = message["sCity"].toString();
await consts.user.storeSignUpInfo(city: consts.user.city);
} else if (message.containsKey("sState")) {
consts.user.state = message["sState"].toString();
await consts.user.storeSignUpInfo(state: consts.user.state);
} else if (message.containsKey("sPostal")) {
consts.user.postalCode = message["sPostal"].toString();
await consts.user
.storeSignUpInfo(postalCode: consts.user.postalCode);
} else if (message.containsKey("sOrganize")) {
consts.user.oraganization = message["sOrganize"].toString();
await consts.user
.storeSignUpInfo(organization: consts.user.oraganization);
}
setState(() {
if (consts.user.userPassword != "" &&
!message.containsKey("delete")) {
/*Future.delayed(Duration.zero, () async {
await consts.user.storeEmailAndPassword(
consts.user.userEmail, consts.user.userPassword);
// controller.loadUrl(
// urlRequest: URLRequest(
// url: Uri.parse(_consts.successDirectUrl +
// "email=${_user.userEmail}&password=${_user.userPassword}")));
});*/
}
});
}
},
onWindowFocus: (controller) async {
var currentUrl = await controller.getUrl();
final html = await controller.getHtml();
var document = parse(html);
if (currentUrl != _currentUrl) {
Future.delayed(Duration.zero, () async {
var htmlCode = await controller.getHtml();
var document = parse(htmlCode);
var currentUrl = await controller.getUrl();
print("currentUrl = ${currentUrl}");
if (document.body!.innerHtml.contains("username#example.com")) {
print("get email");
await consts.user.clearStorage();
// get entered email address
getUserEmail(controller, document.body!.innerHtml);
} else if (document.body!.innerHtml.contains("Root user sign in")) {
print("get pass");
// get entered password
getUserPassword(controller, document.body!.innerHtml);
} else if (currentUrl
.toString()
.contains("https://portal.aws.amazon.com/billing/signup")) {
if (document.body!.innerHtml.contains("AWS account name")) {
print("sign up");
// get signUp email
getSignUpEmail(controller);
// get signUp password
getSignUpPassword(controller);
// get signUp account name
getSignUpAccountName(controller);
} else if (document.body!.innerHtml
.contains("Contact Information")) {
// get full name
getSignUpFullname(controller);
// get phone number
getSignUpPhoneNumber(controller);
// get region
getSignUpRegion(controller);
// get address
getSignUpAddress(controller);
// get city
getSignUpCity(controller);
// get state
getSignUpState(controller);
// get postal code
getSignUpPostalCode(controller);
// get organization
getSignUpOrganization(controller);
}
}
});
}
_currentUrl = currentUrl.toString();
//controller.goBack();
},
onProgressChanged:
(InAppWebViewController controller, int progress) async {
setState(() {
this.progress = progress / 100;
print("progress = ${this.progress}");
});
if (progress == 100) {
var currentUrl = await controller.getUrl();
Future.delayed(Duration(microseconds: 3), () async {
var htmlCode = await controller.getHtml();
var document = parse(htmlCode);
print("currentUrl progress = ${currentUrl.toString()}");
//print("html = ${document.body!.innerHtml}");
if (document.body!.innerHtml
.contains("Email address of your AWS account")) {
print("get email");
await consts.user.clearStorage();
consts.user.userEmail = "";
consts.user.userPassword = "";
controller.evaluateJavascript(source: """
document.querySelector("#new_account_container").style.display = "none";
""");
setState(() {});
// get entered email address
getUserEmail(controller, document.body!.innerHtml);
} else if (document.body!.innerHtml.contains("Root user sign in")) {
print("get pass");
// get entered password
getUserPassword(controller, document.body!.innerHtml);
} else if (currentUrl
.toString()
.contains("https://portal.aws.amazon.com/billing/signup#/")) {
if (document.body!.innerHtml.contains("AWS account name")) {
print("sign up progress");
// get signUp email
getSignUpEmail(controller);
// get signUp password
getSignUpPassword(controller);
// get signUp account name
getSignUpAccountName(controller);
} else if (document.body!.innerHtml
.contains("Contact Information")) {
// get full name
getSignUpFullname(controller);
// get phone number
getSignUpPhoneNumber(controller);
// get region
getSignUpRegion(controller);
// get address
getSignUpAddress(controller);
// get city
getSignUpCity(controller);
// get state
getSignUpState(controller);
// get postal code
getSignUpPostalCode(controller);
// get organization
getSignUpOrganization(controller);
}
}
if (currentUrl.toString() ==
"https://console.aws.amazon.com/iam/home#/users" ||
currentUrl.toString() ==
"https://console.aws.amazon.com/iam/home?#/users") {
print("delete credentials");
// delete user data if loged out
deleteCredentials(controller);
}
});
}
},
);
}
// get user amil
getUserEmail(InAppWebViewController controller, String html) {
controller.addJavaScriptHandler(
handlerName: 'EmailGetter',
callback: (args) {
// print arguments coming from the JavaScript side!
print("email args = $args");
// return data to the JavaScript side!
return args;
});
controller.evaluateJavascript(source: """
document.querySelector("#next_button").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});
""");
}
// getting password
getUserPassword(InAppWebViewController controller, String html) {
controller.evaluateJavascript(source: """
document.querySelector("#signin_button").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"password": document.querySelector("#password").value}));});
""");
}
// getting SignUp Email address
getSignUpEmail(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sEmail": document.querySelector("input[name='email']").value}));});
""");
}
// getting SignUp password
getSignUpPassword(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPassword": document.querySelector("input[name='password']").value}));});
""");
}
// getting SignUp account name
getSignUpAccountName(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sAccountName": document.querySelector("input[name='accountName']").value}));});
""");
}
// getting SignUp fullName
getSignUpFullname(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sFullName": document.querySelector("input[name='address.fullName']").value}));});
""");
}
// getting SignUp phone number
getSignUpPhoneNumber(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPhone": document.querySelector("input[name='address.phoneNumber']").value}));});
""");
}
// getting SignUp region
getSignUpRegion(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sRegion": document.querySelectorAll(".awsui-select-trigger-label")[1].innerText}));});
""");
}
// getting SignUp address
getSignUpAddress(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sAddress": document.querySelectorAll("input[name='address.addressLine1']").value}));});
""");
}
// getting SignUp city
getSignUpCity(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sCity": document.querySelectorAll("input[name='address.city']").value}));});
""");
}
// getting SignUp state
getSignUpState(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sState": document.querySelectorAll("input[name='address.state']").value}));});
""");
}
// getting SignUp postal code
getSignUpPostalCode(controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPostal": document.querySelectorAll("input[name='address.postalCode']").value}));});
""");
}
// getting SignUp organization
getSignUpOrganization(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sOrganize": document.querySelectorAll("input[name='address.company']").value}));});
""");
}
// deleting user credentials
deleteCredentials(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#aws-console-logout").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"delete": "delete"}));});
""");
}
_backButton(BuildContext context) {
return ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back),
);
}
}
Here is much more cleaner code of above code
import 'dart:convert';
import 'package:aws_bot/Utils/Const.dart';
import 'package:aws_bot/Utils/User.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:html/parser.dart';
class signIn extends StatefulWidget {
const signIn({Key? key}) : super(key: key);
#override
_signInState createState() => _signInState();
}
class _signInState extends State<signIn> {
String userEmail = "";
String userPassword = "";
final flutterWebviewPlugin = new FlutterWebviewPlugin();
bool evalJsOnce = false;
String _currentUrl = "";
User _user = User();
bool _loading = true;
double progress = 0.0;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
flutterWebviewPlugin.onProgressChanged.listen((double progress) {
print("progress changed = $progress");
if (progress == 1.0) {
//https://portal.aws.amazon.com/billing/signup
flutterWebviewPlugin.onUrlChanged.listen((String url) {
_currentUrl = url;
print("url changed = $url");
if (url.contains('https://portal.aws.amazon.com/billing/signup')) {
print("signup");
flutterWebviewPlugin.evalJavascript(''
'document.querySelector("#CredentialCollection").addEventListener("submit", function(e) {window.Mchannel.postMessage(JSON.stringify({"email": document.querySelector("#awsui-input-0").value, "password": document.querySelector("#awsui-input-1").value, "confirmPass": document.querySelector("#awsui-input-2").value, "accountName": document.querySelector("#awsui-input-3").value}));});');
} else {
flutterWebviewPlugin.evalJavascript(''
'let pageHtml = document.documentElement.innerHTML;'
'window.Emailchannel.postMessage(pageHtml);'
'if (pageHtml.includes("Root user email address")) {'
'document.querySelector("#next_button").addEventListener("click", function(e) {window.Emailchannel.postMessage(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});}'
'');
}
redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3Ffromtb%3Dtrue%26hashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-east-1_2b2a9061808657b8&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&forceMobileApp=0&code_challenge=-HEkj8kWzXDv2qBLcBQX2GYULvcP2gsHr0p0X_fJJcU&code_challenge_method=SHA-256')) { 'document.querySelector("#next_button").addEventListener("click", function(e) {e.preventDefault(); window.Emailchannel.postMessage(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});;');redirect_uri=https%3A%2F%2Fconsole.aws.amazon.com%2Fconsole%2Fhome%3Ffromtb%3Dtrue%26hashArgs%3D%2523%26isauthcode%3Dtrue%26state%3DhashArgsFromTB_us-east-1_c885b81ed0514ab4&client_id=arn%3Aaws%3Asignin%3A%3A%3Aconsole%2Fcanvas&forceMobileApp=0&code_challenge=_Tqr3pEXTDAqOYjWp0ehE6ToYYSN7OLeyJWBx5HTPVM&code_challenge_method=SHA-256")) { 'document.querySelector("#signin_button").addEventListener("click", function(e) {e.preventDefault(); window.Passwordchannel.postMessage(JSON.stringify({"password": document.querySelector("#password").value}));});;');
});
}
});
flutterWebviewPlugin.onStateChanged.listen((WebViewStateChanged state) {
print("state changed = $state");
});
return Scaffold(
appBar: AppBar(
title: Text(
'AWS Sign In',
style: TextStyle(color: Colors.black),
),
backgroundColor: Colors.yellow[600],
),
floatingActionButton: _backButton(context),
body: Column(
children: [
(progress != 1.0)
? LinearProgressIndicator(
// minHeight: 10.0,
value: progress,
backgroundColor: Colors.redAccent,
valueColor: AlwaysStoppedAnimation<Color>(Colors.black))
: Container(),
Container(
color: Colors.yellow[600],
width: double.infinity,
padding: EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Email Address of you AWS : ${consts.user.userEmail}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
SizedBox(
height: 4.0,
),
Text(
"IAM user name : ${consts.user.accountName}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
SizedBox(
height: 4.0,
),
Text(
"Password : ${consts.user.userPassword != "null" && consts.user.userPassword != "" ? consts.user.userPassword.replaceAll(consts.user.userPassword, "******") : ""}",
style: TextStyle(
fontWeight: FontWeight.w600,
),
),
],
)),
Expanded(child: _buildSignInPage()),
],
),
);
}
_buildSignInPage() {
String _url = "https://console.aws.amazon.com/iam/home#/users";
return InAppWebView(
initialUrlRequest: URLRequest(url: Uri.parse(_url)),
onConsoleMessage: (controller, consoleMessage) async {
print("console message = ${consoleMessage.message}");
print(consoleMessage.messageLevel.toString());
// LOG ERROR => message levels
if (consoleMessage.messageLevel.toString() != "ERROR" &&
consoleMessage.messageLevel.toString() != "WARNING") {
Map message = jsonDecode(consoleMessage.message);
if (message.containsKey("email")) {
consts.user.userEmail = message['email'].toString();
await consts.user.storeSignUpInfo(email: consts.user.userEmail);
} else if (message.containsKey("password")) {
consts.user.userPassword = message['password'].toString();
await consts.user
.storeSignUpInfo(password: consts.user.userPassword);
} else if (message.containsKey("delete")) {
Future.delayed(Duration.zero, () async {
await consts.user.clearStorage();
consts.user.userEmail = "";
consts.user.userPassword = "";
});
} else if (message.containsKey("sEmail")) {
consts.user.userEmail = message['sEmail'].toString();
await consts.user.storeSignUpInfo(email: consts.user.userEmail);
} else if (message.containsKey("sPassword")) {
consts.user.userPassword = message["sPassword"].toString();
await consts.user
.storeSignUpInfo(password: consts.user.userPassword);
} else if (message.containsKey("sAccountName")) {
consts.user.accountName = message["sAccountName"].toString();
await consts.user
.storeSignUpInfo(accountName: consts.user.accountName);
} else if (message.containsKey("sFullName")) {
consts.user.fullName = message["sFullName"].toString();
await consts.user.storeSignUpInfo(fullName: consts.user.fullName);
} else if (message.containsKey("sPhone")) {
consts.user.phoneNumber = message["sPhone"].toString();
await consts.user
.storeSignUpInfo(phoneNumber: consts.user.phoneNumber);
} else if (message.containsKey("sRegion")) {
consts.user.region = message["sRegion"].toString();
await consts.user.storeSignUpInfo(region: consts.user.region);
} else if (message.containsKey("sAddress")) {
consts.user.address = message["sAddress"].toString();
await consts.user.storeSignUpInfo(address: consts.user.address);
} else if (message.containsKey("sCity")) {
consts.user.city = message["sCity"].toString();
await consts.user.storeSignUpInfo(city: consts.user.city);
} else if (message.containsKey("sState")) {
consts.user.state = message["sState"].toString();
await consts.user.storeSignUpInfo(state: consts.user.state);
} else if (message.containsKey("sPostal")) {
consts.user.postalCode = message["sPostal"].toString();
await consts.user
.storeSignUpInfo(postalCode: consts.user.postalCode);
} else if (message.containsKey("sOrganize")) {
consts.user.oraganization = message["sOrganize"].toString();
await consts.user
.storeSignUpInfo(organization: consts.user.oraganization);
}
setState(() {
if (consts.user.userPassword != "" &&
!message.containsKey("delete")) {
}
});
}
},
onWindowFocus: (controller) async {
var currentUrl = await controller.getUrl();
final html = await controller.getHtml();
var document = parse(html);
if (currentUrl != _currentUrl) {
Future.delayed(Duration.zero, () async {
var htmlCode = await controller.getHtml();
var document = parse(htmlCode);
var currentUrl = await controller.getUrl();
print("currentUrl = ${currentUrl}");
if (document.body!.innerHtml.contains("username#example.com")) {
print("get email");
await consts.user.clearStorage();
// get entered email address
getUserEmail(controller, document.body!.innerHtml);
} else if (document.body!.innerHtml.contains("Root user sign in")) {
print("get pass");
// get entered password
getUserPassword(controller, document.body!.innerHtml);
} else if (currentUrl
.toString()
.contains("https://portal.aws.amazon.com/billing/signup")) {
if (document.body!.innerHtml.contains("AWS account name")) {
print("sign up");
// get signUp email
getSignUpEmail(controller);
// get signUp password
getSignUpPassword(controller);
// get signUp account name
getSignUpAccountName(controller);
} else if (document.body!.innerHtml
.contains("Contact Information")) {
// get full name
getSignUpFullname(controller);
// get phone number
getSignUpPhoneNumber(controller);
// get region
getSignUpRegion(controller);
// get address
getSignUpAddress(controller);
// get city
getSignUpCity(controller);
// get state
getSignUpState(controller);
// get postal code
getSignUpPostalCode(controller);
// get organization
getSignUpOrganization(controller);
}
}
});
}
_currentUrl = currentUrl.toString();
//controller.goBack();
},
onProgressChanged:
(InAppWebViewController controller, int progress) async {
setState(() {
this.progress = progress / 100;
print("progress = ${this.progress}");
});
if (progress == 100) {
var currentUrl = await controller.getUrl();
Future.delayed(Duration(microseconds: 3), () async {
var htmlCode = await controller.getHtml();
var document = parse(htmlCode);
print("currentUrl progress = ${currentUrl.toString()}");
//print("html = ${document.body!.innerHtml}");
if (document.body!.innerHtml
.contains("Email address of your AWS account")) {
print("get email");
await consts.user.clearStorage();
consts.user.userEmail = "";
consts.user.userPassword = "";
controller.evaluateJavascript(source: """
document.querySelector("#new_account_container").style.display = "none";
""");
setState(() {});
// get entered email address
getUserEmail(controller, document.body!.innerHtml);
} else if (document.body!.innerHtml.contains("Root user sign in")) {
print("get pass");
// get entered password
getUserPassword(controller, document.body!.innerHtml);
} else if (currentUrl
.toString()
.contains("https://portal.aws.amazon.com/billing/signup#/")) {
if (document.body!.innerHtml.contains("AWS account name")) {
print("sign up progress");
// get signUp email
getSignUpEmail(controller);
// get signUp password
getSignUpPassword(controller);
// get signUp account name
getSignUpAccountName(controller);
} else if (document.body!.innerHtml
.contains("Contact Information")) {
// get full name
getSignUpFullname(controller);
// get phone number
getSignUpPhoneNumber(controller);
// get region
getSignUpRegion(controller);
// get address
getSignUpAddress(controller);
// get city
getSignUpCity(controller);
// get state
getSignUpState(controller);
// get postal code
getSignUpPostalCode(controller);
// get organization
getSignUpOrganization(controller);
}
}
if (currentUrl.toString() ==
"https://console.aws.amazon.com/iam/home#/users" ||
currentUrl.toString() ==
"https://console.aws.amazon.com/iam/home?#/users") {
print("delete credentials");
// delete user data if loged out
deleteCredentials(controller);
}
});
}
},
);
}
// get user amil
getUserEmail(InAppWebViewController controller, String html) {
controller.addJavaScriptHandler(
handlerName: 'EmailGetter',
callback: (args) {
// print arguments coming from the JavaScript side!
print("email args = $args");
// return data to the JavaScript side!
return args;
});
controller.evaluateJavascript(source: """
document.querySelector("#next_button").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"email": document.querySelector("#resolving_input").value}));});
""");
}
// getting password
getUserPassword(InAppWebViewController controller, String html) {
controller.evaluateJavascript(source: """
document.querySelector("#signin_button").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"password": document.querySelector("#password").value}));});
""");
}
// getting SignUp Email address
getSignUpEmail(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sEmail": document.querySelector("input[name='email']").value}));});
""");
}
// getting SignUp password
getSignUpPassword(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPassword": document.querySelector("input[name='password']").value}));});
""");
}
// getting SignUp account name
getSignUpAccountName(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#CredentialCollection").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sAccountName": document.querySelector("input[name='accountName']").value}));});
""");
}
// getting SignUp fullName
getSignUpFullname(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sFullName": document.querySelector("input[name='address.fullName']").value}));});
""");
}
// getting SignUp phone number
getSignUpPhoneNumber(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPhone": document.querySelector("input[name='address.phoneNumber']").value}));});
""");
}
// getting SignUp region
getSignUpRegion(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sRegion": document.querySelectorAll(".awsui-select-trigger-label")[1].innerText}));});
""");
}
// getting SignUp address
getSignUpAddress(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sAddress": document.querySelectorAll("input[name='address.addressLine1']").value}));});
""");
}
// getting SignUp city
getSignUpCity(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sCity": document.querySelectorAll("input[name='address.city']").value}));});
""");
}
// getting SignUp state
getSignUpState(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sState": document.querySelectorAll("input[name='address.state']").value}));});
""");
}
// getting SignUp postal code
getSignUpPostalCode(controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sPostal": document.querySelectorAll("input[name='address.postalCode']").value}));});
""");
}
// getting SignUp organization
getSignUpOrganization(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#ContactInformation").addEventListener("submit", function(ee) {
window.console.log(JSON.stringify({"sOrganize": document.querySelectorAll("input[name='address.company']").value}));});
""");
}
// deleting user credentials
deleteCredentials(InAppWebViewController controller) {
controller.evaluateJavascript(source: """
document.querySelector("#aws-console-logout").addEventListener("click", function(ee) {
window.console.log(JSON.stringify({"delete": "delete"}));});
""");
}
_backButton(BuildContext context) {
return ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back),
);
}
}
In this code you can see also how to use javascript dom manipulation and selection and interaction with web page.

Resources