ActiveListioner Executing after Build Flutter Error - android

I am trying to check firebase database using flutter to see if user who is logged in is registered or not so checking to see if firstname exist in user database but what is happening is that the activeListeners function is always executing after rmn() function which should not happen. activeListeners should execute before rmn() .
Here is my code below:
import 'package:flutter/material.dart';
import 'package:after_layout/after_layout.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:ayto_driver_x/signup.dart';
import 'package:ayto_driver_x/mainpage.dart';
import 'package:ayto_driver_x/login.dart';
import 'package:fluttertoast/fluttertoast.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'After Layout - Good Example',
home: new LoginState(),
);
}
}
class LoginState extends StatefulWidget {
#override
HomeScreenState createState() => new HomeScreenState();
}
class HomeScreenState extends State<LoginState> with AfterLayoutMixin<LoginState> {
FirebaseAuth auth = FirebaseAuth.instance;
String srm="";
final _database=FirebaseDatabase.instance.ref();
#override
void initState() {
// TODO: implement initState
super.initState();
activeListeners();
}
void activeListeners(){
final User? user=auth.currentUser;
final id=user?.uid ;
_database.child('Driver/${user?.uid}/FirstName').onValue.listen((event) {
final Object? description=event.snapshot.value ?? false;
setState(() {
print('DescriptionLS=$description');
srm='$description';
print('SRMx1=$srm');
});
});
}
#override
Widget build(BuildContext context) {
activeListeners();
return new Scaffold(body: new Container(color: Colors.white));
}
#override
void afterFirstLayout(BuildContext context) {
// Calling the same function "after layout" to resolve the issue.
activeListeners();
rmn();
}
void rmn()
{
FirebaseAuth.instance
.authStateChanges()
.listen((User? user) {
if (user == null) {
print('User is currently signed out!');
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => LoginScreen(),
),
(e) => false,
);
}
else {
activeListeners();
print('User is signed in!');
print('SRMxc=$srm');
Fluttertoast.showToast(
msg: srm,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0,
);
if(srm.compareTo('false')==0) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => const SignupScreen(),
),
);
}
else {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => const MainPage(),
),
(e) => false,
);
}
}
});
}
}
Log File :
I/flutter ( 5748): User is signed in!
I/flutter ( 5748): SRMxc=
I/flutter ( 5748): DescriptionLS=false
I/flutter ( 5748): SRMx1=false
I/flutter ( 5748): DescriptionLS=false
I/flutter ( 5748): SRMx1=false
I/flutter ( 5748): DescriptionLS=false
I/flutter ( 5748): SRMx1=false
I/flutter ( 5748): DescriptionLS=false
I/flutter ( 5748): SRMx1=false
Please suggest me a solution to execute activeListeners() before rmn().

Related

iOS implementing camera in flutter

I'm trying to implement the camera package in flutter for android and iOS devices,
On android I don't have any problem but in iOS i get this error:
The following StateError was thrown building Builder:
Bad state: No element
When the exception was thrown, this was the stack:
#0 List.first (dart:core-patch/growable_array.dart:332:5)
#1 _CameraState.initState (package:glass_case_flutter/controllers/camera_controller.dart:21:45)
#2 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4632:57)
#3 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4469:5)
... Normal element mounting (24 frames)
this is the code of main.dart:
List<CameraDescription> cameras;
Future<Null> main() async {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
await Firebase.initializeApp();
runApp(GlassCase());
}
class GlassCase extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(fontFamily: 'Nunito'),
initialRoute: WelcomeScreen.id,
routes: {
WelcomeScreen.id: (context) => WelcomeScreen(),
RegistrationScreen.id: (context) => RegistrationScreen(),
ResetPassword.id: (context) => ResetPassword(),
HomeScreen.id: (context) => HomeScreen(cameras),
ProfileScreen.id: (context) => ProfileScreen()
},
);
}
}
this is the code of my homepage.dart where I call camera.dart:
IconButton(
icon: Icon(Icons.camera_alt),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Camera(widget.cameras)));
},
color: Colors.black,
),
this is my camera.dart, that is very simple, just turn on the camera:
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
class Camera extends StatefulWidget {
List<CameraDescription> cameras;
Camera(this.cameras);
#override
_CameraState createState() => _CameraState();
}
class _CameraState extends State<Camera> {
CameraController controller;
#override
void initState() {
super.initState();
controller =
new CameraController(widget.cameras.first, ResolutionPreset.high);
controller.initialize().then((_) {
if (!mounted) {
return;
}
setState(() {});
});
}
#override
void dispose() {
controller?.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
if (!controller.value.isInitialized) {
return new Container();
}
return new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
);
}
}
I added this in my Info.plist to access the camera and microphone:
<key>NSCameraUsageDescription</key>
<string>Enable to access your camera to capture your photo</string>
<key>NSMicrophoneUsageDescription</key>
<string>Enable to access mic to record your voice</string>
I don't understand why in Android it work but in iOS I get that error, somebody can help me ?
Thank so much !

Flutter asset database error: The getter 'length' was called on null. Receiver: null Tried calling: length

I added my existing database.db file to my project with sqflite. No errors encountered, everything works fine, but... Flutter debug console says:
Restarted application in 772ms.
════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building FutureBuilder<List<Countries>>(dirty, state: _FutureBuilderState<List<Countries>>#d0317):
The getter 'length' was called on null.
Receiver: null
Tried calling: length
The relevant error-causing widget was
FutureBuilder<List<Countries>>
When the exception was thrown, this was the stack
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 _HomeScreen.buildBody.<anonymous closure>
#2 _FutureBuilderState.build
#3 StatefulElement.build
#4 ComponentElement.performRebuild
...
════════════════════════════════════════════════════════════════════════════════
I/flutter (14052): Opening existing database
Here is my model Country.dart :
class Countries {
int countryId;
String countryName;
String countryImageURL;
//Constructor
Countries({this.countryId, this.countryName, this.countryImageURL});
// Extract a Product Object from a Map Oject
Countries.fromMap(Map<String, dynamic> map) {
countryId = map['country_id'];
countryName = map['country_name'];
countryImageURL = map['image'];
}
Map<String, dynamic> toMap() {
var map = <String, dynamic>{
'country_name': countryName,
'image': countryImageURL
};
return map;
}
}
Here is my database_helper.dart file:
import 'dart:async';
import 'dart:io';
import 'package:city_travel_guide/model/Country.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'dart:typed_data';
import 'package:flutter/services.dart';
class DbHelper {
static Database _db;
Future<Database> get db async {
if (_db != null) {
return _db;
} else {
_db = await initDb();
return _db;
}
}
initDb() async {
var dbFolder = await getDatabasesPath();
String path = join(dbFolder, 'app.db');
var exists = await databaseExists(path);
if (!exists) {
// Should happen only the first time you launch your application
print("Creating new copy from asset");
// Make sure the parent directory exists
try {
await Directory(dirname(path)).create(recursive: true);
} catch (_) {}
// Copy from asset
ByteData data = await rootBundle.load(join("assets", "example.db"));
List<int> bytes =
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
// Write and flush the bytes written
await File(path).writeAsBytes(bytes, flush: true);
} else {
print("Opening existing database");
}
// open the database
return await openDatabase(path);
}
Future<List<Countries>> getCountries() async {
var dbClient = await db;
var result = await dbClient.query('Country', orderBy: 'countryId');
return result.map((data) => Countries.fromMap(data)).toList();
}
Here is my main.dart file:
import 'package:city_travel_guide/data/database_helper.dart';
import 'package:city_travel_guide/model/Country.dart';
import 'package:flutter/material.dart';
import 'widgets/maindrawer.dart';
import 'pages/search.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'City Travel Guide',
theme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
home: MyHome());
}
}
class MyHome extends StatefulWidget {
#override
_HomeScreen createState() => _HomeScreen();
}
class _HomeScreen extends State<MyHome> {
List<Countries> countries;
final dbHelper = DbHelper();
#override
void initState() {
dbHelper.initDb();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'City Travel Guide',
style: Theme.of(context).primaryTextTheme.headline6,
),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SearchScreen()),
);
}),
IconButton(icon: const Icon(Icons.more_vert), onPressed: () {}),
],
),
drawer: Drawer(child: MainDrawer()),
body: buildBody(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {},
));
}
buildBody() {
return FutureBuilder<List<Countries>>(
future: dbHelper.getCountries(),
builder: (context, snapshot) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(title: Text(snapshot.data[index].countryName));
},
);
});
}
}
How can I list items on my asset database and view it in application?
FutureBuilder is an asynchronous request. Always check that snapshot has data before building your list.
do:
buildBody() {
return FutureBuilder<List<Countries>>(
future: dbHelper.getCountries(),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data.length > 0) // This ensures that you have at least one or more countries available.
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(title: Text(snapshot.data[index].countryName));
},
);
else if (snapshot.hasData && snapshot.data.length == 0)
return Center(child:Text("There are no countries available"));
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).primaryColor),
)); // This would display a loading animation before your data is ready
});
}
Its to easy you must check if there is a data comming from the future or not before using the snapshot.data.lenght because if the snapshot.data is null(the opperation not finished yet) then lenght was calling on null so you must do it
The correct code
buildBody() {
return FutureBuilder<List<Countries>>(
future: dbHelper.getCountries(),
builder: (context, snapshot) {
if(snapshot.hasdata&&snapshot.data.runtimetype==List){
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return ListTile(title: Text(snapshot.data[index].countryName));
},
);
}else{
return Proggresindicator()//or any loading widgets
}
});
}
}
and you can add check for any execption happens during the future

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(
));

Flutter Bloc Builder is not getting called and not updating UI after state change

I have a problem with Flutter Bloc package. Main idea is to get list of users from API, I turned of the internet to see how my Error state works, but when try/catch block catches an error my Bloc Builder is not getting rebuilt and my UI isn't changing and I have to do hot restart to see the results.
UserBloc class:
import 'dart:io';
import 'package:chopper/chopper.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:listviewblocflutter/bloc/user/user_event.dart';
import 'package:listviewblocflutter/bloc/user/user_state.dart';
import 'package:listviewblocflutter/data/error/network_error.dart';
import 'package:listviewblocflutter/data/service/user_service.dart';
import 'package:listviewblocflutter/model/built/built_user.dart';
import 'package:built_collection/built_collection.dart';
class UserBloc extends Bloc<UserEvent, UserState> {
UserService _userService;
UserBloc() {
this._userService = UserService.create();
}
#override
UserState get initialState => UserInitial();
#override
Stream<UserState> mapEventToState(UserEvent event) async* {
yield UserLoading();
if (event is GetAllUsers) {
print("getallusers");
try {
final listOfUsers = await _userService.getAllUsers();
yield UsersLoaded(listOfUsers.body);
print("users loaded (userBloc)");
} catch (_) {
print("got an error (userBloc)");
yield UserLoadingError("Can't get all users!");
}
} else if (event is GetUserById) {
// single user event
}
}
}
UserEvent class:
import 'package:equatable/equatable.dart';
abstract class UserEvent extends Equatable {
const UserEvent();
}
class GetAllUsers extends UserEvent {
const GetAllUsers();
#override
List<Object> get props => [];
}
class GetUserById extends UserEvent {
final int id;
const GetUserById(this.id);
#override
List<Object> get props => [id];
}
UserState class:
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
import 'package:listviewblocflutter/model/built/built_user.dart';
import 'package:built_collection/built_collection.dart';
#immutable
abstract class UserState extends Equatable {
const UserState();
}
class UserInitial extends UserState {
const UserInitial();
#override
List<Object> get props => [];
}
class UserLoading extends UserState {
const UserLoading();
#override
List<Object> get props => [];
}
class UserLoaded extends UserState {
final BuiltUser user;
const UserLoaded(this.user);
#override
List<Object> get props => [user];
}
class UsersLoaded extends UserState {
final BuiltList<BuiltUser> listOfUsers;
const UsersLoaded(this.listOfUsers);
#override
List<Object> get props => [listOfUsers];
}
class UserLoadingError extends UserState {
final String message;
const UserLoadingError(this.message);
#override
List<Object> get props => [message];
}
class UserEmpty extends UserState {
const UserEmpty();
#override
List<Object> get props => [];
}
I wrapped my HomePage with BlocProvider in main.dart file to get an access of my UserBloc in HomePage:
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'ListView with BLoC pattern',
home: SafeArea(
child: Scaffold(
body: BlocProvider(
create: (context) => UserBloc(), child: HomePage()))),
);
}
}
Tried to make my HomePage class as StateLessWidget, but the problem still occurred, right now my class is StateFulWidget with the same problem. I get AllUsers in initState method:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:listviewblocflutter/bloc/bloc.dart';
import 'package:listviewblocflutter/model/built/built_user.dart';
import 'package:built_collection/built_collection.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
void initState() {
BlocProvider.of<UserBloc>(context).add(GetAllUsers());
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Users"),
),
body: Container(
child: BlocListener<UserBloc, UserState>(
listener: (context, state) {
if (state is UserLoadingError) {
print("showing snackbar (listener)");
_showNetworkErrorSnackbar(context, state.message);
}
},
child: BlocBuilder<UserBloc, UserState>(
builder: (context, state) {
print("bloc builder");
if (state is UserLoading || state is UserInitial)
return _showLoadingStatus();
else if (state is UsersLoaded)
return _buildList(state.listOfUsers);
else if (state is UserEmpty || state is UserLoadingError) {
print("state is empty/error (builder)");
return _emptyListLayout();
}
return Center();
},
),
),
),
);
}
ListView _buildList(BuiltList<BuiltUser> listOfUsers) {
return ListView.builder(
itemCount: listOfUsers.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.redAccent,
),
title: Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
listOfUsers[index].username,
overflow: TextOverflow.ellipsis,
),
),
),
);
});
}
Widget _showLoadingStatus() {
return Center(
child: CircularProgressIndicator(),
);
}
Widget _emptyListLayout() {
return Center(
child: Text(
"List is empty ;(",
textAlign: TextAlign.center,
),
);
}
void _showNetworkErrorSnackbar(BuildContext context, String message) {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(message),
));
}
}
My goal is to tell the user that list is empty and show a snackbar when UserLoadingError state appears, but I only see a stuck LoadingIndicator
My "print" debugger in logs says:
I/flutter (14034): bloc builder
I/flutter (14034): getallusers
I/flutter (14034): bloc builder
I/flutter (14034): got an error (userBloc)
I/flutter (14034): showing snackbar (listener)
Expected results:
I/flutter (14034): bloc builder
I/flutter (14034): getallusers
I/flutter (14034): bloc builder
I/flutter (14034): got an error (userBloc)
I/flutter (14034): showing snackbar (listener) /// a snackbar should appear after this message
I/flutter (14034): bloc builder
I/flutter (14034): state is empty/error (builder) /// an empty list layout should be created after this message
pubspecs.yaml fragment:
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.3
chopper: ^3.0.2
equatable: ^1.1.1
flutter_bloc: ^4.0.0
provider: ^4.1.1
built_value: ^7.1.0
dev_dependencies:
chopper_generator: ^3.0.4
build_runner: ^1.10.0
built_value_generator: ^7.1.0
flutter_test:
sdk: flutter
I could upload my UserService class where I get users from API using Chopper, let me know if it's needed.
Finally I found a problem. The problem was in my BlockBuilder if/else tree, more precisely:
if (state is UserLoading || state is UserInitial)
return _showLoadingStatus();
i changed into:
if (state is UserLoading)
return _showLoadingStatus();
And now the problem disappeared.

Firebase Phone Authentication using Flutter

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.

Categories

Resources