Still raise "firebase_auth/email-already-in-use" exception, although registered an unique email in firebase_auth flutter - firebase

I have a registration state that would handled registration of firebase authentication. From my code, there are two widgets. First (registerForm(context)), it shows registration forms. When "Register" Elevated Button is pressed, they will changed to second widgets (registerProcess(context)) there are processed a registrations.
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:connectivity/connectivity.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:path_provider/path_provider.dart';
class SignUp extends StatefulWidget {
static const routeName = "/signUp";
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _confirmPasswordController = TextEditingController();
final _nameController = TextEditingController();
final auth = FirebaseAuth.instance;
final fireStore = FirebaseFirestore.instance;
final storage = FirebaseStorage.instance;
bool isConnected = false;
bool passwordNotMatch = false;
bool networkWarning = false;
bool emailWarning = false;
bool isSignedUp;
#override
void initState() {
super.initState();
isSignedUp = false;
checkConnectivity();
}
Future<void> checkConnectivity() async {
var conRes = await Connectivity().checkConnectivity();
if (conRes != ConnectivityResult.none) {
isConnected = true;
}
}
Future<UserCredential> _signUp() async {
final validate = await auth.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text);
await auth.currentUser.sendEmailVerification();
final file = await getImgFromAssets("default.png");
await storage.ref("profile/${_emailController.text}.png").putFile(file);
return validate;
}
Future<File> getImgFromAssets(String path) async {
final byteData = await rootBundle.load('assets/$path');
final file = File('${(await getTemporaryDirectory()).path}/$path');
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: isSignedUp ? registerProcess(context) : registerForm(context));
}
Widget registerForm(BuildContext context) {
double height = MediaQuery.of(context).size.height;
// double width = MediaQuery.of(context).size.width;
return SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Sign Up",style: Theme.of(context).textTheme.headline4,),
SizedBox(height: height * 0.02,),
Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Profile Name',
),
controller: _nameController,
),
SizedBox(height: height * 0.02,),
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email Address',
),
controller: _emailController,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Note: Please be unique"),
],
),
emailWarning ? Text("Email is already used", style: TextStyle(color: Colors.red),)
: Container(),
SizedBox(height: height * 0.02,),
TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
),
controller: _passwordController,
),
passwordNotMatch ? Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Password Not Match", style: TextStyle(color: Colors.red),),
],
) : SizedBox(height: 0,),
SizedBox(height: height * 0.02,),
TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Confirm Password',
),
controller: _confirmPasswordController,
),
ElevatedButton(
onPressed: () {
if (!isConnected) {
setState(() {
networkWarning = !networkWarning;
});
} else if (_confirmPasswordController.text != _passwordController.text) {
setState(() {
passwordNotMatch = !passwordNotMatch;
});
}
// else if(_confirmPasswordController.text == null || _passwordController.text == null){}
else {
setState(() {
isSignedUp = !isSignedUp;
});
}
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("Register", style: TextStyle(fontSize: height * 0.025),),
),
),
],
),
),
],
),
),
);
}
Widget registerProcess(BuildContext context) {
return DefaultTextStyle(
style: Theme.of(context).textTheme.headline3,
textAlign: TextAlign.center,
child: FutureBuilder<UserCredential>(
future: _signUp(),
builder: (context, snapshot) {
List<Widget> children;
if (snapshot.hasData) {
children = <Widget>[
const Icon(
Icons.check_circle_outline,
color: Colors.green,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('You\'re registered. Please check your email for verification'),
)
];
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
),
);
} else if (snapshot.hasError) {
print(snapshot.error.toString());
children = <Widget>[
const Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: Email isn\'t valid or already use'),
)
];
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
),
);
} else {
children = <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60,
),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting result...'),
)
];
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
),
);
}
}
)
);
}
}
Although I registered any unique email, it still raise an exception: [firebase_auth/email-already-in-use] The email address is already in use by another account. (Output from print(snapshot.error.toString())). I've checked at my firebase console repeatedly. Are there any mistakes?

Firebase is known for storing some cached data (including authentication and firestore data) in your device once you install the app and start using it's services.
In other words, it's very likely that you're getting this exception because you've deleted the user from firebase but the cached data (which firebase always checks first) is still in your device. Make sure that you really deleted the user in firebase, completely uninstall the app from your device, run flutter clean and then try again. Let me know if it works

Related

firebase firestore chat timestamp order not working corectly

below is my code, i have a chat made in flutter and it should be sorted by timestamp however it is still seemingly random, on firebase it is recording the correct time stamp in json and i thought i had it coded correctly with the firestore.collection order by call. image attached shows the messages they should be ordered 1-6
import 'package:flutter/material.dart';
import 'package:bardsf/constants.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
late String messageText;
class BodyBuildingChat extends StatefulWidget {
static const String id = 'body_building_chat';
#override
_BodyBuildingChatState createState() => _BodyBuildingChatState();
}
class _BodyBuildingChatState extends State<BodyBuildingChat> {
final messageTextController = TextEditingController();
final _firestore = FirebaseFirestore.instance;
final _auth = FirebaseAuth.instance;
late User loggedInUser;
#override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser;
if (user != null) {
loggedInUser = user;
print(loggedInUser.email);
}
} catch (e) {
print (e);
}
}
// void getMessages() async{
// final messages = await _firestore.collection('messages').get();
// for (var message in messages.docs) {
// print(message.data().cast());
// }
// }
void messagesStream() async {
await for( var snapshot in _firestore.collection('bodybuilding').orderBy('timestamp').snapshots()) {
for (var message in snapshot.docs) {
print(message.data().cast());
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: null,
actions: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () {
messagesStream();
_auth.signOut();
Navigator.pop(context);
}),
],
title: Text('🏔Body Building'),
backgroundColor: Colors.lightBlueAccent,
),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
StreamBuilder<QuerySnapshot>(
stream: _firestore.collection('bodybuilding').snapshots(),
builder: (context, snapshot){
List<MessageBubble> messageBubbles = [];
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.lightBlueAccent,
),
);
}
final messages = snapshot.data!.docs.reversed;
for (var message in messages) {
final messageText = message['text'];
final messageSender = message['sender'];
final currentUser = loggedInUser.email;
final messageBubble = MessageBubble(
sender: messageSender,
text: messageText,
isMe: currentUser == messageSender,
);
messageBubbles.add(messageBubble);
}
return Expanded(
child: ListView(
reverse: true,
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
children: messageBubbles,
),
);
},
),
Container(
decoration: kMessageContainerDecoration,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: TextField(
controller: messageTextController,
onChanged: (value) {
messageText = value;
},
decoration: kMessageTextFieldDecoration,
),
),
TextButton(
onPressed: () {
messageTextController.clear();
_firestore.collection('bodybuilding').add({
'text': messageText,
'sender': loggedInUser.email,
'timestamp': FieldValue.serverTimestamp(),
});
},
child: Text(
'Send',
style: kSendButtonTextStyle,
),
),
],
),
),
],
),
),
);
}
}
class MessageBubble extends StatelessWidget {
MessageBubble({required this.sender,required this.text,required this.isMe});
final String sender;
final String text;
final bool isMe;
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children: <Widget>[
Text(sender,
style: TextStyle(
fontSize: 12.0,
),
),
Material(
borderRadius: isMe ? BorderRadius.only(topLeft: Radius.circular(30.0),
bottomLeft: Radius.circular(30.0),
bottomRight: Radius.circular(30.0),
) : BorderRadius.only(topRight: Radius.circular(30.0),
bottomLeft: Radius.circular(30.0),
bottomRight: Radius.circular(30.0),
),
elevation: 5.0,
color: isMe ? Colors.lightBlueAccent : Colors.white,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 8.0),
child: Text('$text',
style: TextStyle( fontSize: 15.0,
color: isMe ? Colors.white : Colors.black,),
),
),
),
],
),
);
}
}
You did not use the appropriate stream.
Change this line
stream: _firestore.collection('bodybuilding').snapshots(),
into this line
stream: _firestore.collection('bodybuilding').orderBy('timestamp').snapshots(),
You will notice that you used the correct stream in the messagesStream but not in the StremBuilder.
Let me know if this does not help.

I cannot retrieve and view data from Firestore Flutter

#HOME: this is home linked to FeatureProducts()
And I cannot retrieve data "product", it always return nil.
I want to retrieve data from Firebase into the Listview.
this is my firebase cloud fire store Image of Firebase Database
i try many time with many ways and all codes doesn't give any errors, but When i run the app and open the activity the data cannot show they will be empty,
import 'package:farmers_ecommerce/commons/common.dart';
import 'package:farmers_ecommerce/db/product.dart';
import 'package:farmers_ecommerce/pages/product_search.dart';
import 'package:farmers_ecommerce/provider/product.dart';
import 'package:farmers_ecommerce/provider/user_provider.dart';
import 'package:farmers_ecommerce/widget/featured_products.dart';
import 'package:farmers_ecommerce/widget/product_card.dart';
import 'package:farmers_ecommerce/widgets/custom_text.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'cart.dart';
import 'order.dart';
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _key = GlobalKey<ScaffoldState>();
ProductServices _productServices = ProductServices();
#override
Widget build(BuildContext context) {
final userProvider = Provider.of<UserProvider>(context);
final productProvider = Provider.of<ProductProvider>(context);
return Scaffold(
key: _key,
backgroundColor: Colors.white,
endDrawer: Drawer(
child: ListView(
children: <Widget>[
UserAccountsDrawerHeader(
decoration: BoxDecoration(color: Colors.black),
accountName: CustomText(
text: userProvider.userModel?.name ?? "username lading...",
color: Colors.white,
weight: FontWeight.bold,
size: 18,
),
accountEmail: CustomText(
text: userProvider.userModel?.email ?? "email loading...",
color: Colors.white,
),
),
ListTile(
onTap: () async{
await userProvider.getOrders();
changeScreen(context, OrdersScreen());
},
leading: Icon(Icons.bookmark_border),
title: CustomText(text: "My orders"),
),
ListTile(
onTap: () async{
userProvider.signOut();
},
leading: Icon(Icons.exit_to_app),
title: CustomText(text: "Log out"),
),
],
),
),
body: SafeArea(
child: ListView(
children: <Widget>[
// Custom App bar
Stack(
children: <Widget>[
Positioned(
top: 10,
right: 20,
child: Align(
alignment: Alignment.topRight,
child: GestureDetector(
onTap: () {
_key.currentState.openEndDrawer();
},
child: Icon(Icons.menu))),
),
Positioned(
top: 10,
right: 60,
child: Align(
alignment: Alignment.topRight,
child: GestureDetector(
onTap: (){
changeScreen(context, CartScreen());
},
child: Icon(Icons.shopping_cart))),
),
Positioned(
top: 10,
right: 100,
child: Align(
alignment: Alignment.topRight, child: GestureDetector(
onTap: (){
_key.currentState.showSnackBar(SnackBar(
content: Text("User profile")));
},
child: Icon(Icons.person))),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'What are\nyou Shopping for?',
style: TextStyle(
fontSize: 30,
color: Colors.black.withOpacity(0.6),
fontWeight: FontWeight.w400),
),
),
],
),
// Search Text field
// Search(),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(20),
bottomLeft: Radius.circular(20))),
child: Padding(
padding: const EdgeInsets.only(
top: 8, left: 8, right: 8, bottom: 10),
child: Container(
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
),
child: ListTile(
leading: Icon(
Icons.search,
color: Colors.black,
),
title: TextField(
textInputAction: TextInputAction.search,
onSubmitted: (pattern)async{
await productProvider.search(productName: pattern);
changeScreen(context, ProductSearchScreen());
},
decoration: InputDecoration(
hintText: "fashion....",
border: InputBorder.none,
),
),
),
),
),
),
// featured products
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(14.0),
child: Container(
alignment: Alignment.centerLeft,
child: new Text('Featured products')),
),
],
),
FeaturedProducts(),
**this is the feature products. i cannot see any thing on here.
its blank**
// recent products
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(14.0),
child: Container(
alignment: Alignment.centerLeft,
child: new Text('Recent products')),
),
],
),
Column(
children: productProvider.products
.map((item) => GestureDetector(
child: ProductCard(
product: item,
),
))
.toList(),
)
],
),
),
);
}
}
#FEATURED PRODUCT: this is linked to ProductProvider which listens from the
database
import 'package:farmers_ecommerce/provider/product.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'featured_card.dart';
class FeaturedProducts extends StatefulWidget {
#override
_FeaturedProductsState createState() => _FeaturedProductsState();
}
class _FeaturedProductsState extends State<FeaturedProducts> {
#override
Widget build(BuildContext context) {
final productProvider = Provider.of<ProductProvider>(context);
return Container(
height: 230,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: productProvider.products.length,
itemBuilder: (_, index) {
return FeaturedCard(
product: productProvider.products[index],
);
}));
}
}
#PRODUCT PROVIDER
//i feel the provider is not loading any products
import 'package:farmers_ecommerce/db/product.dart';
import 'package:farmers_ecommerce/models/product.dart';
import 'package:flutter/material.dart';
class ProductProvider with ChangeNotifier{
ProductServices _productServices = ProductServices();
List<ProductModel> products = [];
List<ProductModel> productsSearched = [];
ProductProvider.initialize(){
loadProducts();
}
loadProducts()async{enter code here
products = await _productServices.getProducts();
notifyListeners();
}
Future search({String productName})async{
productsSearched = await _productServices.searchProducts(productName: productName);
notifyListeners();
}
}
//DATABASE TO FIRESTORE
//I tried using stream builder but it is not working using Future.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:farmers_ecommerce/models/product.dart';
class ProductServices {
String collection = "products";
FirebaseFirestore _firestore = FirebaseFirestore.instance;
Future<List<ProductModel>> getProducts() async =>
_firestore.collection(collection).get().then((result) {
List<ProductModel> products = [];
for (DocumentSnapshot product in result.docs) {
products.add(ProductModel.fromSnapshot(product));
}
return products;
});
Future<List<ProductModel>> searchProducts({String productName}) {
// code to convert the first character to uppercase
String searchKey = productName[0].toUpperCase() + productName.substring(1);
return _firestore
.collection(collection). //return fire base
.orderBy("name")
.startAt([searchKey])
.endAt([searchKey + '\uf8ff'])
.get()
.then((result) {
List<ProductModel> products = [];
for (DocumentSnapshot product in result.docs) {
products.add(ProductModel.fromSnapshot(product));
}
return products;
});
}
}
In your ProductServices change this function:
Future<List<ProductModel>> getProducts() async {
QuerySnapshot result= await _firestore.collection(collection).get();
List<ProductModel> products = [];
for (DocumentSnapshot product in result.docs) {
products.add(ProductModel.fromSnapshot(product));
}
return products;
}
If you use then the return will be called when the code flow already left the function. To avoid that you need to await the result.

Flutter Chat Module with FireStore

Hi i have created a simple Chat module with FireStore everything is working fine both incoming and outgoing messages are being sent. But here's a little bit issue with the flow of List of appearing messages. when message is sent from 1st Emulator it appears randomly on the other Emulator and vise versa.
I tried to reversed the ListView and also the List coming from the SnapShot.
here's the code.
final messages = snapshot.data.docs.reversed;
List<BubbleText> messageBubbles = [];
for (var message in messages) {
final messageText = message.get('text');
final messageSender = message.get('sender');
final currentUser = loggedInUser.email;
final messageWidget = BubbleText(
text: messageText,
sender: messageSender,
isMe: currentUser == messageSender,
);
messageBubbles.add(messageWidget);
}
return Expanded(
child: ListView(
reverse: true,
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
children: messageBubbles,
),
);
This is my ChatScreen.dart file
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flash_chat/constants.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
User loggedInUser;
final fireStore = FirebaseFirestore.instance;
class ChatScreen extends StatefulWidget {
static String chatID = 'chat_screen';
#override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final messageTextController = TextEditingController();
final auth = FirebaseAuth.instance;
String messageText;
#override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() async {
try {
final user = auth.currentUser;
if (user != null) {
loggedInUser = user;
print(loggedInUser.email);
}
} catch (e) {
print(e);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: null,
actions: <Widget>[
IconButton(
icon: Icon(Icons.close),
onPressed: () {
auth.signOut();
Navigator.pop(context);
//Implement logout functionality
}),
],
title: Text('⚡️Chat'),
backgroundColor: Colors.lightBlueAccent,
),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
StreamBuilder<QuerySnapshot>(
stream: fireStore.collection('messages').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.blueAccent,
),
);
}
final messages = snapshot.data.docs.reversed;
List<BubbleText> messageBubbles = [];
for (var message in messages) {
final messageText = message.get('text');
final messageSender = message.get('sender');
final currentUser = loggedInUser.email;
final messageWidget = BubbleText(
text: messageText,
sender: messageSender,
isMe: currentUser == messageSender,
);
messageBubbles.add(messageWidget);
}
return Expanded(
child: ListView(
reverse: true,
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
children: messageBubbles,
),
);
},
),
Container(
decoration: kMessageContainerDecoration,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: TextField(
controller: messageTextController,
onChanged: (value) {
//Do something with the user input.
messageText = value;
},
decoration: kMessageTextFieldDecoration,
),
),
TextButton(
onPressed: () {
messageTextController.clear();
//Implement send functionality.
fireStore.collection('messages').add(
{'text': messageText, 'sender': loggedInUser.email});
},
child: Text(
'Send',
style: kSendButtonTextStyle,
),
),
],
),
),
],
),
),
);
}
}
class BubbleText extends StatelessWidget {
BubbleText({this.text, this.sender, this.isMe});
final String text, sender;
final bool isMe;
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment:
isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children: [
Text(
sender,
style: TextStyle(
color: Colors.black54,
fontSize: 12.0,
),
),
Material(
elevation: 5,
borderRadius: isMe
? BorderRadius.only(
topLeft: Radius.circular(30),
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30))
: BorderRadius.only(
topRight: Radius.circular(30),
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30)),
color: isMe ? Colors.blueAccent : Colors.white,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Text(
text,
style: TextStyle(
color: isMe ? Colors.white : Colors.black,
fontSize: 15,
),
),
),
),
],
),
);
}
}
i spent over 3 hrs on it but couldn't find a proper solution.
you can add a timesTamp field in the messages document, So every single message should have a timestamp and when you read the data try to sort it by that timesTamp, it is worked with me, and DON'T forget to remove the revered property from the List Widget
here is my suggestion :
final messages = snapshot.data.docs;
if(messages != null){
messages = messages..sort((a,b)=>a.timesTamp>b.timestamp);
}
List<BubbleText> messageBubbles = [];
for (var message in messages) {
final messageText = message.get('text');
final messageSender = message.get('sender');
final currentUser = loggedInUser.email;
final messageWidget = BubbleText(
text: messageText,
sender: messageSender,
isMe: currentUser == messageSender,
);
messageBubbles.add(messageWidget);
}
return Expanded(
child: ListView(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
children: messageBubbles,
),
);
Just reverse your list like this when you define your list
final chatList = data.reversed.toList();

SetState to a String returns null, Firestore with Flutter

I have a splash screen where I want to control the followig:
1. If user is loged out, take the user to OnBoardingScreen.
2. If user is loged in, but has no data in firestore. Take the user to SetupAccountPage
3. If user is loged in and had data to go to HomePage.
My problem is the string value(_controller) returns null. when the user is loged out and works fine when the user is loged in. I'm confused. I gave the code some time to load but doesn't help.
Please help for anyone who has an idea what is wrong here.
Below is my code
import 'dart:async';
import 'package:app/model/user.dart';
import 'package:app/pages/HomePage.dart';
import 'package:app/pages/SetupAccountPage.dart';
import 'package:app/screens/home/home.dart';
import 'package:app/screens/onboarding.dart';
import 'package:app/screens/setup_profile.dart';
import 'package:app/shared/loading.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Wrapper extends StatefulWidget {
#override
_WrapperState createState() => _WrapperState();
}
class _WrapperState extends State<Wrapper> {
//FirebaseUser user;
String onlineUserId;
String _controller;
#override
void initState() {
super.initState();
_checkUser();
Timer(Duration(seconds: 5), () {
print('done');
if (_controller == 'out') {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => OnBoardingScreen(),
),
);
} else if (_controller == 'info') {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SetupAccountPage(),
),
);
} else if (_controller == 'home') {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage(),
),
);
}
;
});
}
_checkUser() async {
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
final uid = user.uid;
if (await FirebaseAuth.instance.currentUser() == null) {
setState(() {
_controller = 'out';
});
} else {
final snapShot =
await Firestore.instance.collection('Users').document(user.uid).get();
if (snapShot.exists) {
setState(() {
_controller = 'home';
});
// Document with id == docId doesn't exist.
} else {
setState(() {
_controller = 'info';
});
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(color: Colors.redAccent),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 2,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircleAvatar(
backgroundColor: Colors.white,
radius: 50.0,
child: Icon(
Icons.shopping_cart,
color: Colors.greenAccent,
size: 50.0,
),
),
Padding(
padding: EdgeInsets.only(top: 10.0),
),
Text(
'this is a name',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 24.0),
)
],
),
),
),
Expanded(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(),
Padding(
padding: EdgeInsets.only(top: 20.0),
),
Text(
'another name',
softWrap: true,
textAlign: TextAlign.center,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.white),
)
],
),
)
],
)
],
),
);
}
}
I finally found the answer. The reson was geting the user was returning a future and this was the missing code.
Future<FirebaseUser> getUser() async {
return await _auth.currentUser();
}

How to get array data back to mobile screen from firebase (Flutter)

How to get back array data to the mobile screen.
The String in the firebase is retrieved easily but I have problem with array data.
1) main.dart :
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'firestoreservice.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'taskscreen.dart';
import 'task.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter ToDo APP',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: Color(0xff543B7A),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<Task> items;
FirestoreService fireServ = new FirestoreService();
StreamSubscription<QuerySnapshot> todoTasks;
#override
void initState() {
super.initState();
items=new List();
todoTasks?.cancel();
todoTasks=fireServ.getTaskList().listen((QuerySnapshot snapshot){
final List<Task> tasks=snapshot.documents
.map((documentSnapshot) => Task. fromMap(documentSnapshot.data))
.toList();
setState(() {
this.items = tasks;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Column(
children: <Widget>[
_myAppBar(context),
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height - 80,
child: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Stack(children: <Widget>[
// The containers in the background
Column(children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 8.0, right: 8.0),
child: Container(
width: MediaQuery.of(context).size.width,
height: 80.0,
child: Padding(
padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
child: Material(
color: Colors.white,
elevation: 14.0,
shadowColor: Color(0x802196F3),
child: Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
'${items[index].name}',
style: TextStyle(
color: Colors.black,
fontSize: 20.0),
),
Text(
'${items[index].size}',
style: TextStyle(
color: Colors.black,
fontSize: 20.0),
),
Container(
child: Image.network(
'${items[index].imageU}',
)),
],
),
),
),
),
),
),
),
]),
]);
}),
),
],
),
);
}
Widget todoType(String icontype) {
IconData iconval;
Color colorval;
switch (icontype) {
case 'travel':
iconval = FontAwesomeIcons.mapMarkerAlt;
colorval = Color(0xff4158ba);
break;
case 'shopping':
iconval = FontAwesomeIcons.shoppingCart;
colorval = Color(0xfffb537f);
break;
case 'gym':
iconval = FontAwesomeIcons.dumbbell;
colorval = Color(0xff4caf50);
break;
case 'party':
iconval = FontAwesomeIcons.glassCheers;
colorval = Color(0xff9962d0);
break;
default:
iconval = FontAwesomeIcons.tasks;
colorval = Color(0xff0dc8f5);
//
}
return CircleAvatar(
backgroundColor: colorval,
child: Icon(iconval, color: Colors.white, size: 20.0),
);
}
Widget _myAppBar(context) {
return Container(
height: 80.0,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
const Color(0xFFFA7397),
const Color(0xFFFDDE42),
],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 0.0),
stops: [0.0, 1.0],
tileMode: TileMode.clamp),
),
child: Padding(
padding: const EdgeInsets.only(top: 16.0),
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 5,
child: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'ToDo Tasks',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20.0),
),
),
),
),
Expanded(
flex: 1,
child: Container(
child: IconButton(
icon: Icon(
FontAwesomeIcons.search,
color: Colors.white,
),
onPressed: () {
//
}),
),
),
],
)),
),
);
}
}
2) task.dart
class Task{
String _name;
String _size;
Task(this._name ,this._size);
Task.map(dynamic obj){
this._name = obj['name'];
this._size=obj['size'];
List<String> imageU= new List<String>();
}
String get name=> _name;
String get size=>_size;
Task.fromMap(Map<String,dynamic> map){
this._name = map['name'];
this._size= map['size'];
this.imageU= List.from(map['images']);
}
}
3) firestoreservice.dart
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'task.dart';
final CollectionReference myCollection =
Firestore.instance.collection('products');
class FirestoreService {
Future<Task> createTODOTask(String name, String size) async {
final TransactionHandler createTransaction = (Transaction tx) async {
final DocumentSnapshot ds = await tx.get(myCollection.document());
};
return Firestore.instance.runTransaction(createTransaction).then((mapData) {
return Task.fromMap(mapData);
}).catchError((error) {
print('error: $error');
return null;
});
}
Stream<QuerySnapshot> getTaskList({int offset, int limit}) {
Stream<QuerySnapshot> snapshots = myCollection.snapshots();
if (offset != null) {
snapshots = snapshots.skip(offset);
}
if (limit != null) {
snapshots = snapshots.take(limit);
}
return snapshots;
}
}
How to get back array data to the mobile screen. The String in the firebase is retrieved easily but I have a problem with array data.
Convert task.dart to see what solution will work:
class Task{
String name;
List<String> size= new List<String>();
Task.fromMap(Map<String,dynamic> map){
this.name = map['name'];
this.size= List.from(map['size' ]);
}
}
And make sure all the documents in the image have "size" field.

Resources