Firebase Phone Authentication using Flutter - android

Hi Im new in flutter and trying to use firebase phone authentication by using flutter. however, when I try to press the button, I get the following error.
I am using AndroidStudio.
Xcode build done. 21.5s
path: satisfied (Path is satisfied), interface: en0
Configuring the default Firebase app...
Configured the default Firebase app __FIRAPP_DEFAULT.
path: satisfied (Path is satisfied), interface: en0
Syncing files to device iPhone 11 Pro Max...
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23c7127e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff513fbb20 objc_exception_throw + 48
2 CoreFoundation 0x00007fff23c710bc +[NSException raise:format:] + 188
3 Runner 0x0000000103e97d81 -[FIRPhoneAuthProvider verifyPhoneNumber:UIDelegate:completion:] + 193
4 Runner 0x000000010440dc3d -[FLTFirebaseAuthPlugin handleMethodCall:result:] + 18109
5 Flutter 0x000000010600ddb5 __45-[FlutterMethodChannel setMethodCallHandler:]_block_invoke + 104
6 Flutter 0x0000000105fa1ba0 _ZNK7flutter21PlatformMessageRouter21HandlePlatf<…>
Lost connection to device.
This is my code. Please someone help me
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
// initialRoute: '/',
// routes: {
// '/' : (context) => WelcomeClass(),
// '/LoginClass' : (context) => LoginClass(),
// '/SignUpClass' : (context) => SignUpClass(),
// },
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String phoneNo;
String smsCode;
String verificationId;
Future<void> verifyPhone() async {
final PhoneCodeAutoRetrievalTimeout autoRetrieve = (String verId) {
this.verificationId = verId;
};
final PhoneCodeSent smsCodeSent = (String verId, [int forceCodeResend]) {
this.verificationId = verId;
smsCodeDialog(context).then((value){
print('signed in');
});
};
final PhoneVerificationCompleted verificationSuccess = (AuthCredential user){
print('Phone Verification Completed');
};
final PhoneVerificationFailed verificationFailed =
(AuthException exception) {
print('${exception.message}');
};
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: this.phoneNo,
codeAutoRetrievalTimeout: autoRetrieve,
codeSent: smsCodeSent,
timeout: const Duration(seconds: 60),
verificationCompleted: verificationSuccess,
verificationFailed: verificationFailed,
);
}
Future<bool> smsCodeDialog(BuildContext context) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return new AlertDialog(
title: Text('Enter sms code'),
content: TextField(
onChanged: (value) {
this.smsCode = value;
},
),
contentPadding: EdgeInsets.all(10),
actions: <Widget>[
FlatButton(
child: Text('Done'),
onPressed: () {
FirebaseAuth.instance.currentUser().then((user) {
if (user != null) {
Navigator.of(context).pop();
Navigator.of(context)
.pushReplacementNamed('/SignUpClass');
} else {
Navigator.of(context).pop();
signIn();
}
});
},
)
],
);
});
}
signIn() {
final AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: verificationId, smsCode: smsCode);
FirebaseAuth.instance.signInWithCredential(credential).then((user) {
Navigator.of(context).pushReplacementNamed('/homepage');
}).catchError((e) {
print('Auth Credential Error : $e');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(38.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextField(
onChanged: (value) {
this.phoneNo = value;
},
),
SizedBox(
height: 40,
),
FlatButton(
child: Text("Send code"),
onPressed: verifyPhone,
), //FlatButton
], // Widget
),
), // Column
);
}
}
I feel that there is something wrong with the flutter I installed.
Ive also tried to run on my real phone but it crashed too.

Related

LateInitializationError error in firebase auth code in flutter [duplicate]

This is the middle part of the main that is expected to cause the error. If you are not logged in on the splash screen, this code goes to MyHomePage and logs in. If you are logged in, it goes to MainScreen and switches to the main screen of the app.
class SplashScreen extends StatefulWidget {
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
final FirebaseAuth auth = FirebaseAuth.instance;
final User? user = FirebaseAuth.instance.currentUser;
#override
void initState() {
super.initState();
_initUser().whenComplete((){
setState(() {});
});
}
_initUser() async {
if (auth.currentUser != null) {
Timer(
Duration(seconds: 2),
() => Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) =>
MainScreen(user!)),
(Route<dynamic> route) => false),
);
} else {
Timer(Duration(seconds: 1),
() => Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) =>
MyHomePage()),
(Route<dynamic> route) => false),
);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Splash Screen"),
),
);
}
}
This is the MyHomePage widget that is passed when you are not logged in.
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: TextButton(
onPressed: (){
FirebaseService().signup(context);
},
child: Text('Google'),
),
)
);
}
}
class FirebaseService{
final FirebaseAuth auth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();
Future<void> signup(BuildContext context) async {
final GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn();
if (googleSignInAccount != null) {
final GoogleSignInAuthentication googleSignInAuthentication =
await googleSignInAccount.authentication;
final AuthCredential authCredential = GoogleAuthProvider.credential(
idToken: googleSignInAuthentication.idToken,
accessToken: googleSignInAuthentication.accessToken);
// Getting users credential
UserCredential result = await auth.signInWithCredential(authCredential);
User? user = result.user;
if (user != null) {
Navigator.push(
context, MaterialPageRoute(builder: (context) => MainScreen(user)));
} // if result not null we simply call the MaterialpageRoute,
// for go to the HomePage screen
}
}
Future<void> signOutFromGoogle() async{
await googleSignIn.signOut();
await auth.signOut();
}
}
This is the content of the error
The following LateError was thrown building MainScreen(dirty, dependencies: [_InheritedProviderScope<Pro?>], state: _MainScreenState#d95a0):
LateInitializationError: Field '_instance#640075166' has not been initialized.
The relevant error-causing widget was:
MainScreen MainScreen:file:///F:/flutter%20project/good_man/lib/main.dart:75:25
When the exception was thrown, this was the stack:
Sorry, I forgot the mainscreen code. Below is the mainscreen code
class MainScreen extends StatefulWidget {
const MainScreen(this.user);
final User user;
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
#override
Widget build(BuildContext context) {
final User user = widget.user;
final pro = Provider.of<Pro>(context);
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(60.0), // here the desired height
child: AppBar(
iconTheme: IconThemeData(color: Colors.black),
backgroundColor: pro.backColor_main,
elevation: 0.0,
centerTitle: true,
title: Text('aaa',
style: TextStyle(
fontFamily: 'Gugi',
fontSize: 20.sp,
color: Colors.black,
),),
),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.white
),
),
ListTile(
title: Text('aaa'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
bottomNavigationBar: BottomBar(),
body: Stack(children: [
TabBarView(
children: [
MainTest(),
Text(''),
Main_User(user),
],
),
])),
);
}
}
Sorry for posting all the code. There is no part that uses late , but the error code is displayed as late, and I try to delete the caches and start
Actually error is in Initialisation of current user...
You have to understand Life cycle of stateful widget...
initState is not holding flow. it just initialise some some instance value...And you try to delay for 2 sec... So that's the issue.
Use FutureBuilder for _initUser() and when it fetch all data then proceed for the next screen.
Don't initialise the async task into the initState. Because of Flutter Life Cycle it can not await the flow...
For more about the lIfe Cycle please visit this:
Life Cycle of Widget
So Solution is...
Use the FutureBuilder for awaiting the widget....
class SplashScreen extends StatefulWidget {
#override
_SplashScreenState createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
final FirebaseAuth auth = FirebaseAuth.instance;
final User? user = FirebaseAuth.instance.currentUser;
_initUser() async {
if (auth.currentUser != null) {
Timer(
Duration(seconds: 2),
() => Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) =>
MainScreen(user!)),
(Route<dynamic> route) => false),
);
} else {
Timer(Duration(seconds: 1),
() => Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(
builder: (context) =>
MyHomePage() ),
(Route<dynamic> route) => false),
);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _initUser(),
builder: (context, snapshot) {
if(snapshot.hasData){
//You you finish the initialization
return Text("You Get the Data");
}
//Until the data get
return Center(child: Text("Splash Screen"),);
},
),
);
}
}

How to open my app by a link in a new tab?

I'm adding deep linking to my app, i'm using uni_links https://pub.dev/packages/uni_links.
everything works fine but the app opens in the same tab as the link, and not in a new one.
how can I make the app open in another tab?
example in the image: the app opens on the hangouts tab, instead of go back to it's own tab.
You should use flutter dynamic links
You should read this documentation enter link description here
current veriosn: firebase_dynamic_links: ^2.0.4
Example:
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(MaterialApp(
title: 'Dynamic Links Example',
routes: <String, WidgetBuilder>{
'/': (BuildContext context) => _MainScreen(),
'/helloworld': (BuildContext context) => _DynamicLinkScreen(),
},
));
}
class _MainScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() => _MainScreenState();
}
class _MainScreenState extends State<_MainScreen> {
String? _linkMessage;
bool _isCreatingLink = false;
String _testString =
'To test: long press link and then copy and click from a non-browser '
"app. Make sure this isn't being tested on iOS simulator and iOS xcode "
'is properly setup. Look at firebase_dynamic_links/README.md for more '
'details.';
#override
void initState() {
super.initState();
initDynamicLinks();
}
Future<void> initDynamicLinks() async {
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData? dynamicLink) async {
final Uri? deepLink = dynamicLink?.link;
if (deepLink != null) {
// ignore: unawaited_futures
Navigator.pushNamed(context, deepLink.path);
}
}, onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
});
final PendingDynamicLinkData? data =
await FirebaseDynamicLinks.instance.getInitialLink();
final Uri? deepLink = data?.link;
if (deepLink != null) {
// ignore: unawaited_futures
Navigator.pushNamed(context, deepLink.path);
}
}
Future<void> _createDynamicLink(bool short) async {
setState(() {
_isCreatingLink = true;
});
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: 'https://cx4k7.app.goo.gl',
link: Uri.parse('https://dynamic.link.example/helloworld'),
androidParameters: AndroidParameters(
packageName: 'io.flutter.plugins.firebasedynamiclinksexample',
minimumVersion: 0,
),
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short,
),
iosParameters: IosParameters(
bundleId: 'com.google.FirebaseCppDynamicLinksTestApp.dev',
minimumVersion: '0',
),
);
Uri url;
if (short) {
final ShortDynamicLink shortLink = await parameters.buildShortLink();
url = shortLink.shortUrl;
} else {
url = await parameters.buildUrl();
}
setState(() {
_linkMessage = url.toString();
_isCreatingLink = false;
});
}
#override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
appBar: AppBar(
title: const Text('Dynamic Links Example'),
),
body: Builder(builder: (BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: !_isCreatingLink
? () => _createDynamicLink(false)
: null,
child: const Text('Get Long Link'),
),
ElevatedButton(
onPressed: !_isCreatingLink
? () => _createDynamicLink(true)
: null,
child: const Text('Get Short Link'),
),
],
),
InkWell(
onTap: () async {
if (_linkMessage != null) {
await launch(_linkMessage!);
}
},
onLongPress: () {
Clipboard.setData(ClipboardData(text: _linkMessage));
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Copied Link!')),
);
},
child: Text(
_linkMessage ?? '',
style: const TextStyle(color: Colors.blue),
),
),
Text(_linkMessage == null ? '' : _testString)
],
),
);
}),
),
);
}
}
class _DynamicLinkScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Material(
child: Scaffold(
appBar: AppBar(
title: const Text('Hello World DeepLink'),
),
body: const Center(
child: Text('Hello, World!'),
),
),
);
}
}

Flutter Error, Exception caught by gesture, The following _CastError was thrown while handling a gesture: Null check operator used on a null value

Whenever I tried to do login and tap on the login button then I am having this type of problem with the null check operator used on null values.
This is the error message that I got:
════════ Exception caught by gesture ═══════════════════════════════════════════
The following _CastError was thrown while handling a gesture:
Null check operator used on a null value
When the exception was thrown, this was the stack
#0 _AuthFormState._trySubmit package://FlutterChat/widgets/auth_form.dart:46
#1 _InkResponseState._handleTap
#2 GestureRecognizer.invokeCallback
#3 TapGestureRecognizer.handleTapUp
#4 BaseTapGestureRecognizer._checkUp
Handler: "onTap"
Recognizer: TapGestureRecognizer#c9833
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(165.5, 228.0)
finalLocalPosition: Offset(19.0, 13.5)
button: 1
sent tap down
This is my auth_form.dart file:
import 'package:flutter/material.dart';
import 'dart:io';
import './user_image_picker.dart';
class AuthForm extends StatefulWidget {
AuthForm(this.submitFn, this.isLoading);
final bool isLoading;
final Future<void> Function(String email, String password, String username,
File image, bool isLogin, BuildContext ctx) submitFn;
#override
_AuthFormState createState() => _AuthFormState();
}
class _AuthFormState extends State<AuthForm> {
final _formKey = GlobalKey<FormState>();
var _isLogin = true;
dynamic _userEmail = '';
dynamic _userName = '';
dynamic _userPassword;
File? _userImageFile;
void _pickedImage(File? image) {
_userImageFile = image;
}
//Form validation and save
_trySubmit() {
final isValid = _formKey.currentState?.validate();
FocusScope.of(context).unfocus();
if (_userImageFile == null && !_isLogin) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Please Select an Image'),
backgroundColor: Theme.of(context).errorColor,
));
return;
}
if (isValid!) {
_formKey.currentState?.save();
widget.submitFn(
_userEmail?.trim(),
_userPassword?.trim(),
_userName?.trim(),
_userImageFile!,
_isLogin,
context,
);
}
}
//Form Widget
#override
Widget build(BuildContext context) {
return new Builder(
builder: (context) {
return Center(
child: Card(
margin: EdgeInsets.all(20),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
if (!_isLogin) UserImagePicker(_pickedImage),
TextFormField(
key: ValueKey('email'),
autocorrect: false,
textCapitalization: TextCapitalization.none,
enableSuggestions: false,
validator: (value) {
if (value?.isEmpty == null || !value!.contains('#')) {
return 'Please Enter valid Email Address.';
}
return null;
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email Address',
),
onSaved: (value) {
_userEmail = value;
},
),
if (!_isLogin)
TextFormField(
key: ValueKey('username'),
autocorrect: true,
textCapitalization: TextCapitalization.words,
enableSuggestions: false,
validator: (value) {
if (value!.isEmpty) {
return 'Please Enter Username.';
}
return null;
},
decoration: InputDecoration(
labelText: 'Username',
),
onSaved: (value) {
_userName = value;
}),
TextFormField(
key: ValueKey('password'),
validator: (value) {
if (value?.isEmpty == null || value!.length < 7) {
return 'Password must be atleast 7 characters long';
}
return null;
},
obscureText: true,
decoration: InputDecoration(
labelText: 'Password',
),
onSaved: (value) {
_userPassword = value;
}),
SizedBox(
height: 12,
),
if (widget.isLoading) CircularProgressIndicator(),
if (!widget.isLoading)
ElevatedButton(
child: Text(_isLogin ? 'Login' : 'Signup'),
onPressed: _trySubmit,
),
if (!widget.isLoading)
TextButton(
child: Text(_isLogin
? 'Create a new account'
: 'I already have an account'),
style: TextButton.styleFrom(primary: Colors.pink),
onPressed: () {
setState(() {
_isLogin = !_isLogin;
});
},
),
],
),
),
),
),
),
);
},
);
}
}
This is my auth_screen.dart file:
import 'package:FlutterChat/screens/conversion_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../widgets/auth_form.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:io';
import 'package:firebase_storage/firebase_storage.dart';
//import 'package:firebase_core/firebase_core.dart';
class AuthScreen extends StatefulWidget {
#override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
//FirebaseAuth _auth = FirebaseAuth.instance;
var _isLoading = false;
//Submit AuthCredential Function
Future<void> submitAuthForm(String? email, String? password, String? username,
File? image, bool isLogin, BuildContext ctx) async {
UserCredential userCredential;
try {
setState(() {
_isLoading = true;
});
if (isLogin) {
userCredential = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email!, password: password!);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ConversionScreen()));
} else {
userCredential = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email!, password: password!);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ConversionScreen()));
final ref = FirebaseStorage.instance
.ref()
.child('user_image')
.child(userCredential.user!.uid + '.jpg');
await ref.putFile(image!).whenComplete(() => print('Image Upload'));
final url = await ref.getDownloadURL();
await FirebaseFirestore.instance
.collection('users')
.doc(userCredential.user?.uid)
.set({
'username': username,
'email': email,
'imageUrl': url,
});
}
} on PlatformException catch (error) {
dynamic message = 'An error occured, please check your credentials!';
if (error.message != null) {
message = error.message;
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Theme.of(ctx).errorColor,
),
);
setState(() {
_isLoading = false;
});
} catch (error) {
print(error);
setState(() {
_isLoading = false;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: AuthForm(submitAuthForm, _isLoading),
);
}
}
If someone knows then please help me.
The error is occurring due to this line,
_userImageFile!,
What I suspect is that your if clause,
if (_userImageFile == null && !_isLogin) {
is not protecting it from not being null, since the if clause would be false if _isLogin is true despite _userImageFile being null.
One way to fix this would be to do remove the bang operator since you can also have a case of calling the submitFn when your _isLogin is true and in that case, you definitely won't have a non null _userImageFile.
_userImageFile, // while calling widget.submitFn
Then make sure you change your `submitFn' function type to
final Future<void> Function(String email, String password, String username,
// add the ? for File image
File? image, bool isLogin, BuildContext ctx) submitFn;
Since your, submitAuthForm already says File? image, nothing to change there.
in auth_form.dart,use this process..check the image enter image description here

This happens because you used a `BuildContext` that does not include the provider of your choice

I am Working on Flutter App Both for web and mobile and stuck at the Following Error:
======== Exception caught by widgets library =======================================================
The following ProviderNotFoundException was thrown building Products(dirty):
Error: Could not find the correct Provider<List<ProductsModel>> above this Products Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that Products is under your MultiProvider/Provider<List<ProductsModel>>.
This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>()),
),
}
```
consider using `builder` like so:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context) {
// No longer throws
return Text(context.watch<Example>()),
}
),
}
```
The relevant error-causing widget was:
Products file:///E:/Flutter%20Projects/flutter_web_firebase_host/lib/screens/home/home.dart:37:63
When the exception was thrown, this was the stack:
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49 throw_
packages/provider/src/provider.dart 332:7 _inheritedElementOf
packages/provider/src/provider.dart 284:30 of
packages/flutter_web_firebase_host/screens/databaseScreens/products.dart 10:31 build
packages/flutter/src/widgets/framework.dart 4569:28 build
...
====================================================================================================
Main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_web_firebase_host/model/users.dart';
import 'package:flutter_web_firebase_host/provider/product_provider.dart';
import 'package:flutter_web_firebase_host/screens/wrapper.dart';
import 'package:flutter_web_firebase_host/services/auth.dart';
import 'package:flutter_web_firebase_host/services/firestore_service.dart';
import 'package:provider/provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
final firestoreServise = FirestoreService();
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => ProductProvider(),
),
StreamProvider(
create: (context) => firestoreServise.getProducts(),
initialData: [],
),
StreamProvider<Users>.value(
value: AuthService().user,
initialData: null,
),
],
/* child: StreamProvider<Users>.value(
value: AuthService().user,
initialData: null*/
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: Wrapper(),
),
);
// );
}
Product.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_web_firebase_host/model/ProductModel.dart';
import 'package:flutter_web_firebase_host/screens/databaseScreens/edit_product.dart';
import 'package:provider/provider.dart';
class Products extends StatelessWidget {
#override
Widget build(BuildContext context) {
final products = Provider.of<List<ProductsModel>>(context, listen: false);
return Scaffold(
appBar: AppBar(
title: Text('Products'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => EditProduct()));
}),
],
),
body: (products != null)
? ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(products[index].name),
trailing: Text(products[index].price.toString()),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => EditProduct(products[index])));
},
);
},
)
: Center(child: CircularProgressIndicator()));
}
}
Home.dart
import 'package:flutter/material.dart';
import 'package:flutter_web_firebase_host/screens/databaseScreens/products.dart';
import 'package:flutter_web_firebase_host/services/auth.dart';
import 'package:flutter_web_firebase_host/shared/drawer.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
backgroundColor: Colors.brown[100],
appBar: AppBar(
title: Text('Brew Crew'),
backgroundColor: Colors.brown[100],
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
icon: Icon(Icons.person),
label: Text('logout'),
onPressed: () async {
await _auth.signOut();
},
),
IconButton(
icon: Icon(Icons.add, color: Colors.black),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => Products()));
}),
],
),
body: SingleChildScrollView(
child: Center(
child: Column(
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(0.0, 50, 0, 0),
child: Container(
child: Text(
'Stock Market',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
)),
),
),
Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 0, 0),
child: Image.asset(
"assets/graph.jpg",
width: 500,
height: 600,
),
),
),
],
),
),
),
drawer: MyDrawer(),
),
);
}
}
product_provider.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter_web_firebase_host/model/ProductModel.dart';
import 'package:flutter_web_firebase_host/services/firestore_service.dart';
import 'package:uuid/uuid.dart';
class ProductProvider with ChangeNotifier {
final firestoreService = FirestoreService();
String _name;
double _price;
String _productId;
var uuid = Uuid();
//Geters
String get name => _name;
double get price => _price;
//Seters
changeName(String value) {
_name = value;
notifyListeners();
}
changePrice(String value) {
_price = double.parse(value);
notifyListeners();
}
loadValues(ProductsModel product) {
_name=product.name;
_price=product.price;
_productId=product.productId;
}
saveProduct() {
print(_productId);
if (_productId == null) {
var newProduct = ProductsModel(name: name, price: price, productId: uuid.v4());
firestoreService.saveProduct(newProduct);
} else {
//Update
var updatedProduct =
ProductsModel(name: name, price: _price, productId: _productId);
firestoreService.saveProduct(updatedProduct);
}
}
}
Authservise.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_web_firebase_host/model/users.dart';
import 'package:google_sign_in/google_sign_in.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// create user obj based on firebase user
Users _userFromFirebaseUser(User user) {
return user != null ? Users(uid: user.uid) : null;
}
// auth change user stream
Stream<Users> get user {
return _auth.authStateChanges().map(_userFromFirebaseUser);
}
// sign in anon
Future signInAnon() async {
try {
UserCredential result = await _auth.signInAnonymously();
User user = result.user;
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
// sign in with email and password
Future signInWithEmailAndPassword(String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
User user = result.user;
return user;
} catch (error) {
print(error.toString());
return null;
}
}
// register with email and password
Future registerWithEmailAndPassword(String email, String password) async {
try {
UserCredential result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
User user = result.user;
return _userFromFirebaseUser(user);
} catch (error) {
print(error.toString());
return null;
}
}
// sign out
Future signOut() async {
try {
return await _auth.signOut();
} catch (error) {
print(error.toString());
return null;
}
}
//sign in with google
Future<bool> loginWithGoogle() async {
try {
GoogleSignIn googleSignIn = GoogleSignIn();
GoogleSignInAccount account = await googleSignIn.signIn();
if(account == null )
return false;
UserCredential res = await _auth.signInWithCredential(GoogleAuthProvider.credential(
idToken: (await account.authentication).idToken,
accessToken: (await account.authentication).accessToken,
));
if(res.user == null)
return false;
return true;
} catch (e) {
print(e.message);
print("Error logging with google");
return false;
}
}
}
Basically my app is connect to firebase both for web app and android app. Also i send data to firestore from my app but when i click the add button to go to textfield to send data it give the error as i mention it in start. I am using multiprovider as you can see my main.dart code
Is There anything I missing. I need Help.
the way to fix this is to put MultiProvider as parent of myApp in your main like this
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => ProductProvider(),
),
StreamProvider(
create: (context) => firestoreServise.getProducts(),
initialData: [],
),
StreamProvider<Users>.value(
value: AuthService().user,
initialData: null,
),
],
child:MyApp(
));

Image_picker throws removeInvalidNode all the node in jank list is out of time instead of returning image

I am trying to choose image with gallery or camera and display with image_picker.
When I run the app in android, I am able to choose image but not displaying. In contrast I am getting following in the console for the first time.
I/HwViewRootImpl(11213): removeInvalidNode all the node in jank list is out of time
If I repeat the same, it gives following in each time while press the button instead of opening gallery or camera.
I/flutter (11213): PlatformException(already_active, Image picker is already active, null)
I found following solutions from my search but not solved my case.
flutter clean , flutter clean
changing the version of the plugin
updating all dependencies
using retrieveLostData method as stated in the plugin documentation
Following is the code I have used for retrieve image:
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class CameraApp extends StatefulWidget {
#override
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
File imageFile;
#override
void initState() {
super.initState();
}
Future _getImage(int type) async {
print("Called Image Picker");
var image = await ImagePicker.pickImage(
source: type == 1 ? ImageSource.camera : ImageSource.gallery,
);
setState(() {
print("$image.path");
imageFile = image;
});
}
Future<void> retrieveLostData() async {
final LostDataResponse response = await ImagePicker.retrieveLostData();
if (response == null) {
return;
}
if (response.file != null) {
setState(() {
if (response.type == RetrieveType.image) {
imageFile = response.file;
}
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Image Editor"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
imageFile != null
? Image.file(
imageFile,
height: MediaQuery.of(context).size.height / 2,
)
: Text("Image editor"),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text("Add Slip"),
content: Row(
children: <Widget>[
Expanded(
child: new FlatButton(
child: new Text("Camera"),
onPressed: () {
_getImage(1);
Navigator.pop(context);
},
),
),
Expanded(
child: new FlatButton(
child: new Text("Gallery"),
onPressed: () {
_getImage(2);
Navigator.pop(context);
},
),
)
],
),
);
},
);
},
tooltip: 'Pick Image',
child: Icon(Icons.camera),
),
);
}
}
I've tried the sample code that you've shared and for some reason got compiler issues but not the same issue as yours. Therefore, I've tried to debug your code. Here is the fixed code:
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
File imageFile;
#override
void initState() {
super.initState();
}
Future _getImage(int type) async {
print("Called Image Picker");
var image = await await ImagePicker.platform.pickImage(
source: type == 1 ? ImageSource.camera : ImageSource.gallery,
);
setState(() {
print("$image.path");
imageFile = File(image.path);
});
}
Future<void> retrieveLostData() async {
final LostData response = await ImagePicker.platform.retrieveLostData();
if (response == null) {
return;
}
if (response.file != null) {
setState(() {
if (response.type == RetrieveType.image) {
imageFile = response.file as File;
}
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Image Editor"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
imageFile != null
? Image.file(
imageFile,
height: MediaQuery.of(context).size.height / 2,
)
: Text("Image editor"),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text("Add Slip"),
content: Row(
children: <Widget>[
Expanded(
child: new FlatButton(
child: new Text("Camera"),
onPressed: () {
_getImage(1);
Navigator.pop(context);
},
),
),
Expanded(
child: new FlatButton(
child: new Text("Gallery"),
onPressed: () {
_getImage(2);
Navigator.pop(context);
},
),
)
],
),
);
},
);
},
tooltip: 'Pick Image',
child: Icon(Icons.camera),
),
);
}
}
Few of the fixes are these lines:
var image = await await ImagePicker.pickImage(
source: type == 1 ? ImageSource.camera : ImageSource.gallery,
);
It's having an error in the compiler so I've changed it to this:
var image = await await ImagePicker.platform.pickImage(
source: type == 1 ? ImageSource.camera : ImageSource.gallery,
);
Same to these lines:
Future<void> retrieveLostData() async {
final LostData response = await ImagePicker.retrieveLostData();
if (response == null) {
return;
}
if (response.file != null) {
setState(() {
if (response.type == RetrieveType.image) {
imageFile = response;
}
});
}
}
Fixed version:
Future<void> retrieveLostData() async {
final LostData response = await ImagePicker.platform.retrieveLostData();
if (response == null) {
return;
}
if (response.file != null) {
setState(() {
if (response.type == RetrieveType.image) {
imageFile = response.file as File;
}
});
}
}
and this
setState(() {
print("$image.path");
imageFile = image;
}
to this:
setState(() {
print("$image.path");
imageFile = File(image.path);
}
The reason could be the version of image_picker that I'm using. Currently I'm using the image_picker: ^0.7.4.
Here is actual output:
I've also encounter an issue if your running this in an Android API version 30, you get this error:
Unhandled Exception: PlatformException(no_available_camera, No cameras available for taking pictures., null, null)
The workaround is to add <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/> in manifest as mentioned in this GitHub post.

Categories

Resources