Edit User Profile Page and Profile Picture. Using Real-Time Database flutter - firebase

I am trying to pull user data from my UserProfileBrowse Data model and display it on my user profile edit page. Including the image. I also want to update the data into my real-time Database.
THIS IS MY DATA MODEL
class UserProfileBrowse {
String userId;
int age;
String name;
String email;
String imageUrl;
UserProfileBrowse(
this.userId,
this.age,
this.name,
this.email,
this.imageUrl,
);
Map<dynamic, dynamic> toJson() => <dynamic, dynamic>{
'userId': userId,
'age': age,
'name': name,
'email': email,
'imageUrl' : imageUrl,
};
}
THIS IS MY USER PROFILE EDIT PAGE
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/auth.dart';
import 'home.dart';
import 'settings.dart';
import 'package:shadow_app_project/data_models/user_profile_browse.dart';
import 'package:shadow_app_project/image_selection/user_edit_image.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
class SettingsUI extends StatelessWidget {
const SettingsUI({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: "Setting UI",
home: EditProfilePage(),
);
}
}
class EditProfilePage extends StatefulWidget {
const EditProfilePage({Key? key}) : super(key: key);
#override
_EditProfilePageState createState() => _EditProfilePageState();
}
class _EditProfilePageState extends State<EditProfilePage> {
String currentUser = (Auth().auth.currentUser as User).email.toString();
TextEditingController displayNameController = TextEditingController();
TextEditingController ageController = TextEditingController();
bool isLoading = false;
User? user;
UserProfileBrowse? userModel;
String? imageUrl;
final refDatabase = FirebaseDatabase.instance;
bool showPassword = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
elevation: 1,
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
color: Colors.green,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => const SettingsPage()));
},
),
actions: [
IconButton(
icon: const Icon(
Icons.settings,
color: Colors.green,
),
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => const SettingsPage()));
},
),
],
),
body: Container(
padding: const EdgeInsets.only(left: 16, top: 25, right: 16),
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: ListView(
children: [
const Text(
"Edit Profile",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w500),
),
const SizedBox(
height: 15,
),
Container(
width: 130,
height: 130,
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Theme.of(context).scaffoldBackgroundColor),
boxShadow: [
BoxShadow(
spreadRadius: 2,
blurRadius: 10,
color: Colors.black.withOpacity(0.1),
offset: const Offset(0, 10))
],
shape: BoxShape.circle,
image: const DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://images.pexels.com/photos/3307758/pexels-photo-3307758.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=250",
))),
),
const SizedBox(
height: 35,
),
TextField(
decoration: const InputDecoration(
labelText: "Name",
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.teal)),
hintText: 'Input Name',
),
controller: displayNameController,
keyboardType: TextInputType.name,
),
TextField(
decoration: const InputDecoration(
labelText: "Age",
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.teal)),
hintText: 'Input Age',
),
controller: ageController,
//
keyboardType: TextInputType.number,
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Text("Email: ", style: TextStyle(fontSize: 20),),
),
const SizedBox(
height: 35,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
onPressed: () {},
child: const Text("CANCEL",
style: TextStyle(
fontSize: 14,
letterSpacing: 2.2,
color: Colors.black)),
),
TextButton(
onPressed: () {
FirebaseDatabase.instance.ref()
.child('useProfileBrowse')
.child(user!.uid)
.update({
'name': displayNameController.text //yes I know.
});
FirebaseDatabase.instance.ref()
.child('useProfileBrowse')
.child(user!.uid)
.update({
'age': ageController.text //yes I know.
});
},
child: const Text(
"SAVE",
style: TextStyle(
fontSize: 14,
letterSpacing: 2.2,
color: Colors.white),
),
)
],
)
],
),
),
),
);
}
}
I am thinking to use a StreamBuilder in my body: with stream: FirebaseDatabase.instance.ref().child('userProfileBrowse').child(user!.uid).onValue,
Any idea how can I display User profile Imageurl, name, and age from my real-time Database
And also edit the information using stream builder or any other method
I have just coded the UI for my profile edit page. I just want someone to help me retrieve data from my data model class and display it on my user edit page. A single line to display just a name from my data model will help a lot to understand how retrieving data works. I have already saved data(imageUrl, name, age) into my data models during the signup process. Just want to display it

full example with StreamProvider :
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Person {
Person({required this.name, required this.initialAge});
final String name;
final int initialAge;
Stream<String> get age async* {
var i = initialAge;
while (i < 85) {
await Future.delayed(const Duration(seconds: 1), () {
i++;
});
yield i.toString();
}
}
}
void main() {
runApp(
StreamProvider<String>(
create: (_) => Person(name: 'Yohan', initialAge: 25).age,
initialData: 25.toString(),
catchError: (_, error) => error.toString(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Future Provider"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Consumer<String>(
builder: (context, String age, child) {
return Column(
children: <Widget>[
const Text("Watch Yohan Age..."),
const Text("name: Yohan"),
Text("age: $age"),
],
);
},
),
),
),
);
}
}

You already started to use the Provider as a state management, so I'd recommend using StreamProvider like this:
StreamProvider<String>(
create: (_) => Profile(name: 'Yohan', initialImageURL: ''),
initialData: ''.toString(),
catchError: (_, error) => error.toString(),
child: child(),
builder: (context) {
// Pretend this is loading data and reporting the percent loaded.
},
),
)
or you can just notify the UI every time you have got a change from the firebase using ChangeNotifier,
for examples, visit Docs

Related

Download image to phone directory

I've created a flutter project that show a staggeredgridview of images from firestore database. Once i click on one of the images it shows that image. What i want is a download button thats saves the image to my device. Ath the moment I've just used pop.
I've read some about the path provider package but i can't figure out how to implement this in the code. Perhaps there is a better solution?
StaggeredGridView Page
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:proj/screens/home/instafull.dart';
import 'dart:async';
import 'package:proj/services/auth.dart';
import 'package:proj/shared/constants.dart';
class Instapage extends StatefulWidget {
#override
_InstapageState createState() => _InstapageState();
}
class _InstapageState extends State<Instapage> {
final AuthService _auth = AuthService();
StreamSubscription<QuerySnapshot> subscription;
List<DocumentSnapshot> wallpaperlist;
final CollectionReference collectionReference = FirebaseFirestore.instance.collection('mediapost');
#override
void initState() {
// TODO: implement initState
super.initState();
subscription = collectionReference.snapshots().listen((datasnapshot) {
setState(() {
wallpaperlist = datasnapshot.docs;
});
});
}
#override
void dispose() {
subscription?.cancel();
// TODO: implement dispose
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: bas,
body: wallpaperlist != null?
StaggeredGridView.countBuilder(
padding: const EdgeInsets.fromLTRB(10, 8, 10, 0),
crossAxisCount: 4,
itemCount: wallpaperlist.length,
itemBuilder: (context, index){
String imgPath = wallpaperlist[index].get('img');
return new Material(
elevation: 8,
borderRadius: BorderRadius.all(Radius.circular(8.0)),
child: InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => InstaFull(imgPath: imgPath))),
child: Hero(
tag: imgPath,
child: FadeInImage(
image: NetworkImage(imgPath),
fit: BoxFit.cover,
placeholder: AssetImage('assets/wally2.jpg'),
),
),
),
);
},
staggeredTileBuilder: (index) => StaggeredTile.count(2, index.isEven?2:3),
mainAxisSpacing: 8,
crossAxisSpacing: 8,
): Center(
child: CircularProgressIndicator(),
),
);
}
}
Picture Page
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
class InstaFull extends StatelessWidget {
String imgPath;
InstaFull({this.imgPath});
final LinearGradient backgroundGradient = LinearGradient(
colors: [Color(0x10000000), Color(0x30000000)],
begin: Alignment.topLeft,end: Alignment.bottomRight);
#override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox.expand(
child: Stack(
children: [
Align(
alignment: Alignment.center,
child: Hero(
tag: imgPath,
child: Image.network(imgPath),
),
),
Align(
alignment: Alignment.topCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
leading: IconButton(
icon: Icon(Icons.close,
color: Colors.black,
),
onPressed: () => Navigator.of(context).pop(),
),
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('Download')),
],),
)
],
),
),
);
}
}
You can use gallery_saver
Install it and enable this permissions:
iOS
Add the following keys to your Info.plist file, located in <project root>/ios/Runner/Info.plist:
NSPhotoLibraryUsageDescription - describe why your app needs permission for the photo library. This is called Privacy - Photo Library Usage Description in the visual editor.
Android
Android
android.permission.WRITE_EXTERNAL_STORAGE - Permission for usage of external storage
Official example of gallery_saver:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gallery_saver/gallery_saver.dart';
import 'package:image_picker/image_picker.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String firstButtonText = 'Take photo';
String secondButtonText = 'Record video';
double textSize = 20;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
color: Colors.white,
child: Column(
children: <Widget>[
Flexible(
flex: 1,
child: Container(
child: SizedBox.expand(
child: RaisedButton(
color: Colors.blue,
onPressed: _takePhoto,
child: Text(firstButtonText,
style:
TextStyle(fontSize: textSize, color: Colors.white)),
),
),
),
),
Flexible(
child: Container(
child: SizedBox.expand(
child: RaisedButton(
color: Colors.white,
onPressed: _recordVideo,
child: Text(secondButtonText,
style: TextStyle(
fontSize: textSize, color: Colors.blueGrey)),
),
)),
flex: 1,
)
],
),
),
));
}
void _takePhoto() async {
ImagePicker.pickImage(source: ImageSource.camera)
.then((File recordedImage) {
if (recordedImage != null && recordedImage.path != null) {
setState(() {
firstButtonText = 'saving in progress...';
});
GallerySaver.saveImage(recordedImage.path).then((String path) {
setState(() {
firstButtonText = 'image saved!';
});
});
}
});
}
void _recordVideo() async {
ImagePicker.pickVideo(source: ImageSource.camera)
.then((File recordedVideo) {
if (recordedVideo != null && recordedVideo.path != null) {
setState(() {
secondButtonText = 'saving in progress...';
});
GallerySaver.saveVideo(recordedVideo.path).then((String path) {
setState(() {
secondButtonText = 'video saved!';
});
});
}
});
}
void _saveNetworkVideo() async {
String path =
'https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4';
GallerySaver.saveVideo(path).then((bool success) {
setState(() {
print('Video is saved');
});
});
}
void _saveNetworkImage() async {
String path =
'https://image.shutterstock.com/image-photo/montreal-canada-july-11-2019-600w-1450023539.jpg';
GallerySaver.saveImage(path).then((bool success) {
setState(() {
print('Image is saved');
});
});
}
}

How to save user data in cloud fire store in flutter

I am using a package called lit_firebase_auth which makes firebase authentication easier to handle. I want to be able to save user data, such as the username after the user logs in. Basically as such:
User logs in or signs up --> User clicks on edit profile page from the home screen --> User can enter their desired name in the text field and click save --> Saves this data to the cloud of the respectful logged in user.
Please I'm a beginner and I have no idea how to pull this off.
Here is the code for reference:
cloud_firebase.dart:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
Future<void> userSetup(String displayName) async {
CollectionReference users = FirebaseFirestore.instance.collection('Users');
FirebaseAuth auth = FirebaseAuth.instance;
String uid = auth.currentUser.uid.toString();
users.add({'displayName': displayName, 'uid': uid});
return;
}
auth.dart
import 'package:flutter/material.dart';
import 'package:kiwi/screens/auth/register.dart';
import 'package:kiwi/screens/background_painter.dart';
import 'package:lit_firebase_auth/lit_firebase_auth.dart';
import 'package:kiwi/screens/auth/sign_in.dart';
import 'package:animations/animations.dart';
import 'package:kiwi/screens/home.dart';
class AuthScreen extends StatefulWidget {
const AuthScreen({Key key}) : super(key: key);
static MaterialPageRoute get route => MaterialPageRoute(
builder: (context) => const AuthScreen(),
);
#override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen>
with SingleTickerProviderStateMixin {
AnimationController _controller;
ValueNotifier<bool> showSignInPage = ValueNotifier<bool>(true);
#override
void initState() {
_controller =
AnimationController(vsync: this, duration: const Duration(seconds: 2));
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: LitAuth.custom(
onAuthSuccess: () {
Navigator.of(context).pushReplacement(HomeScreen.route);
},
child: Stack(
children: [
SizedBox.expand(
child: CustomPaint(
painter: BackgroundPainter(),
)),
Center(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 800),
child: ValueListenableBuilder<bool>(
valueListenable: showSignInPage,
builder: (context, value, child) {
return PageTransitionSwitcher(
reverse: !value,
duration: Duration(milliseconds: 800),
transitionBuilder:
(child, animation, secondaryAnimation) {
return SharedAxisTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
transitionType: SharedAxisTransitionType.vertical,
fillColor: Colors.transparent,
child: child,
);
},
child: value
? SignIn(
key: ValueKey('SignIn'),
onRegisterClicked: () {
context.resetSignInForm();
showSignInPage.value = false;
_controller.forward();
},
)
: Register(
key: ValueKey('Register'),
onSignInPressed: () {
context.resetSignInForm();
showSignInPage.value = true;
_controller.reverse();
},
),
);
},
),
),
),
],
),
),
);
}
}
splash.dart
import 'package:flutter/material.dart';
import 'package:lit_firebase_auth/lit_firebase_auth.dart';
import 'package:kiwi/screens/home.dart';
import 'package:kiwi/screens/auth/auth.dart';
class SplashScreen extends StatelessWidget {
const SplashScreen({Key key}) : super(key: key);
static MaterialPageRoute get route => MaterialPageRoute(
builder: (context) => const SplashScreen(),
);
#override
Widget build(BuildContext context) {
final user = context.watchSignedInUser();
user.map(
(value) {
_navigateToHomeScreen(context);
},
empty: (_) {
_navigateToAuthScreen(context);
},
initializing: (_) {},
);
return const Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
);
}
void _navigateToAuthScreen(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback(
(_) => Navigator.of(context).pushReplacement(AuthScreen.route),
);
}
void _navigateToHomeScreen(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback(
(_) => Navigator.of(context).pushReplacement(HomeScreen.route),
);
}
}
edit_profile.dart
import 'package:flutter/material.dart';
import 'package:kiwi/config/palette.dart';
import 'package:kiwi/screens/auth/decoration_functions.dart';
class Profile extends StatefulWidget {
const Profile({Key key}) : super(key: key);
static MaterialPageRoute get route => MaterialPageRoute(
builder: (context) => const Profile(),
);
_ProfileState createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
// UserModel _currentUser = locator.get<UserController>().currentUser;
// File _image;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Edit Profile'),
),
body: Builder(
builder: (context) => Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(
height: 20.0,
),
Column(
children: <Widget>[
Text(
'Hey there',
style: TextStyle(color: Palette.lightGreen, fontSize: 20),
)
],
),
SizedBox(
height: 20,
),
Expanded(
flex: 8,
child: ListView(
children: [
Padding(
padding: EdgeInsets.fromLTRB(50, 0, 50, 0),
child: TextFormField(
style: const TextStyle(
fontSize: 18,
color: Colors.green,
),
decoration: signInInputDecoration(
hintText: 'New Username',
),
),
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
elevation: 4,
color: Colors.red,
onPressed: () {
Navigator.of(context).pop();
},
child: const Text(
'Cancel',
style: TextStyle(color: Colors.white),
),
),
RaisedButton(
elevation: 4,
color: Palette.lightGreen,
onPressed: () {
Navigator.of(context).pop();
},
child: const Text(
'Save',
style: TextStyle(color: Colors.white),
),
),
],
),
],
),
),
],
),
),
),
);
}
}
to save user data to document in firebase using uuid for document name the below code will work.
if you are confused about how to use the code in your app its simple.
just follow the steps:
call userSetup Function from onpress while passing the display name data.
how to use
the below code will create new document using the currect users uuid in firestore in user collection and save the data.
onPress:(){
userSetup(displayName:"zakriakhan");
}
userSteup Function
Future<void> userSetup(String displayName) async {
//firebase auth instance to get uuid of user
FirebaseAuth auth = FirebaseAuth.instance.currentUser();
//now below I am getting an instance of firebaseiestore then getting the user collection
//now I am creating the document if not already exist and setting the data.
FirebaseFirestore.instance.collection('Users').document(auth.uid).setData(
{
'displayName': displayName, 'uid': uid
})
return;
}

Different content for different user Flutter

I've been building an app where users can make a reservation for cat grooming. I already connected the app to Firebase where users can register and log in to the app. Here is the problem, every time I log in with different user account, the reservation history from the other users still there.
How can I make different content for different users that login? so each user can have their own content.
Here is the code from history page.
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class HistoryPage extends StatefulWidget {
static const String id = 'HistoryPage';
#override
_HistoryPageState createState() => _HistoryPageState();
}
class _HistoryPageState extends State<HistoryPage> {
final _firestore = Firestore.instance;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(25.0, 68.0, 70.0, 25.0),
child: Text(
'History',
style: TextStyle(fontSize: 35.0),
),
),
Column(
children: <Widget>[
StreamBuilder<QuerySnapshot>(
stream: _firestore.collection('ReservationData').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
final messages = snapshot.data.documents;
List<HistoryBox> historyWidgets = [];
for (var message in messages) {
final historyDate = message.data['Reservation Date'];
final historyTime = message.data['Reservation Time'];
final historyWidget =
HistoryBox(date: historyDate, time: historyTime);
historyWidgets.add(historyWidget);
}
return Column(
children: historyWidgets,
);
},
),
],
)
],
)),
);
}
}
class HistoryBox extends StatelessWidget {
final String date;
final String time;
HistoryBox({this.date, this.time});
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 25.0),
child: Material(
elevation: 5.0,
child: Container(
child: Text(
'Date Reservation : \n $date and $time',
style: TextStyle(
fontSize: 20.0,
),
),
),
),
);
}
}
(Updated)
This is the code for users to sign up.
import 'package:flutter/material.dart';
import 'package:project_pi/screens/HomePage/home_page.dart';
import 'inputform_signup.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class SignUpPage extends StatefulWidget {
static const String id = 'SignUpPage';
#override
_SignUpPageState createState() => _SignUpPageState();
}
class _SignUpPageState extends State<SignUpPage> {
final _firestore = Firestore.instance;
final _auth = FirebaseAuth.instance;
bool showSpinner = false;
String nama;
String email;
String password;
String phoneNumber;
#override
Widget build(BuildContext context) {
return Scaffold(
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Form(
child: SafeArea(
child: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'SIGN UP',
style: TextStyle(
fontSize: 28.0,
),
),
InputForm(
hint: 'Full Name',
hidetext: false,
onChanged: (value) {
nama = value;
},
),
InputForm(
hint: 'Email Address',
hidetext: false,
onChanged: (value) {
email = value;
},
),
InputForm(
hint: 'Phone Number',
hidetext: false,
onChanged: (value) {
phoneNumber = value;
},
),
InputForm(
hint: 'Password',
hidetext: true,
onChanged: (value) {
password = value;
},
),
InputForm(
hint: 'Confirm Password',
hidetext: true,
),
SizedBox(height: 15.0),
Container(
height: 45.0,
width: 270.0,
child: RaisedButton(
child: Text('SIGN UP'),
onPressed: () async {
setState(() {
showSpinner = true;
});
try {
final newUser =
await _auth.createUserWithEmailAndPassword(
email: email, password: password);
_firestore.collection('UserAccount').add({
'Email Address': email,
'Full Name': nama,
'Phone Number': phoneNumber,
});
if (newUser != null) {
Navigator.pushNamed(context, HomePage.id);
}
setState(() {
showSpinner = false;
});
} catch (e) {
print(e);
}
},
),
),
SizedBox(
height: 15.0,
),
Text('Have an Account?'),
SizedBox(
height: 7.5,
),
InkWell(
child: Text(
'SIGN IN',
style: TextStyle(
color: Colors.red,
),
),
onTap: () {
AlertDialog(
title: Text("Finish?"),
content: Text("Are you sure with the data?"),
actions: <Widget>[
FlatButton(onPressed: null, child: null)
],
);
},
),
],
),
),
),
),
),
),
);
}
}
And this is the class for the current user that logged in
import 'package:flutter/material.dart';
import 'package:project_pi/screens/HomePage/homebutton.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:project_pi/screens/LiveMaps/live_maps.dart';
import 'package:project_pi/screens/LoginPage/HalamanLogin.dart';
import 'package:project_pi/screens/ReservationHistory/history_page.dart';
import 'package:project_pi/screens/ReservationPage/information_detail.dart';
class HomePage extends StatefulWidget {
static const String id = "HomePage";
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _auth = FirebaseAuth.instance;
FirebaseUser loggedInUser;
#override
void initState() {
super.initState();
getCurrentUser();
}
void getCurrentUser() async {
try {
final user = await _auth.currentUser();
if (user != null) {
loggedInUser = user;
}
} catch (e) {
print(e);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Expanded(
child: Container(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(25.0, 68.0, 256.0, 47.0),
child: Text(
'Home',
style: TextStyle(fontSize: 35.0),
),
),
Center(
child: Column(
children: <Widget>[
HomeNavButton(
prefixIcon: Icons.date_range,
textbutton: 'Make Reservation',
onPressed: () {
Navigator.pushNamed(context, InformationDetail.id);
},
),
SizedBox(
height: 40.0,
),
HomeNavButton(
prefixIcon: Icons.list,
textbutton: 'Reservation History',
onPressed: () {
Navigator.pushNamed(context, HistoryPage.id);
},
),
SizedBox(
height: 40.0,
),
HomeNavButton(
prefixIcon: Icons.gps_fixed,
textbutton: 'Live Maps Track',
onPressed: () {
Navigator.pushNamed(context, LiveMaps.id);
},
),
SizedBox(
height: 40.0,
),
HomeNavButton(
prefixIcon: Icons.person,
textbutton: 'Account Profile',
onPressed: () {
FirebaseAuth.instance.signOut();
Navigator.pushNamed(context, HalamanLogin.id);
},
),
],
),
),
],
),
),
),
),
);
}
}
how to implement the filter for each current user that logged in so it can show the content based on users?
when user creates an account via firebase they get assigned a uid userId which can be obtained by
String userId;
getCurrentUser() async {
FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
setState(() {
userId = firebaseUser.uid;
});
}
and then while saving reservations you can include a field "userId":userid
now when you query you can query for your currentUser
_firestore.collection('ReservationData') .where("userId", isEqualTo: userId).snapshots(),

Read data from Firebase database and display the details as the widget loads

In my flutter project, I want to read data from the Firebase Database of the current user logged in and display the User name from the database and display at the appbar[Line 43:title: Text('$userName'),] of the Page.I had tried by the following code below but it gives error on line 26[Line:final FirebaseUser user = _auth.currentUser();]. The error is on the keyword '_auth.currentUser()'
Error is:A value of type 'Future' can't be assigned to a variable of type 'FirebaseUser'
Here is the code:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:udharibook/Screens/UserProfile.dart';
import 'package:udharibook/services/authservice.dart';
import 'Customer_Support.dart';
import 'package:udharibook/services/UserData.dart';
class DashboardPage extends StatefulWidget {
#override
_DashboardPageState createState() => _DashboardPageState();
}
class _DashboardPageState extends State<DashboardPage> {
List<UserData> userdata = [];
String userName;
#override
void initState()
{
super.initState();
FirebaseAuth _auth = FirebaseAuth.instance;
DatabaseReference DBRef = FirebaseDatabase.instance.reference().child('Users');
final FirebaseUser user = _auth.currentUser();
DBRef.child(user.uid).once().then((DataSnapshot user)
{
userName = user.value['Name'];
setState(() {
print(userName);
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('$userName'),
backgroundColor: Color.fromRGBO(162, 42, 43, 1.0),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: () {
print("Search Clicked");
}),
IconButton(
icon: Icon(Icons.sort),
onPressed: () {
print("Sort Clicked");
}),
],
),
drawer: Drawer(
child: ListView(
children: <Widget>[
DrawerHeader(
child: Text("mehul jain"),
decoration: BoxDecoration(
color: Color.fromRGBO(162, 42, 43, 1.0),
),
),
CustomMenu(
Icons.person,
'Profile',() => {
Navigator.pop(context),
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => UserProfile()))
}),
CustomMenu(Icons.assessment, 'Reports', () => {}),
CustomMenu(Icons.settings, 'Settings', () => {}),
CustomMenu(
Icons.perm_phone_msg,
'Customer Support',
() => {
Navigator.pop(context),
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => CustSupport()))
}),
CustomMenu(Icons.lock, 'Log Out', () => {AuthService().signOut()}),
],
),
),
);
}
}
class CustomMenu extends StatelessWidget {
IconData icon;
String text;
Function onTap;
CustomMenu(this.icon, this.text, this.onTap);
#override
Widget build(BuildContext context) {
// TODO: implement build
return Padding(
padding: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.0),
child: Container(
decoration: BoxDecoration(
border:
Border(bottom: BorderSide(color: Colors.grey.shade400))),
child: InkWell(
splashColor: Colors.redAccent,
onTap: onTap,
child: Container(
height: 60.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
Icon(icon),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
text,
style: TextStyle(
fontSize: 17.0, fontFamily: 'Exo2'),
)),
],
),
Icon(Icons.arrow_right),
],
),
))));
}
}
currentUser() returns a Future<FirebaseUser>, therefore you have to do the following:
_auth.currentUser().then((curUser)
{
DBRef.child(curUser.uid).once().then((DataSnapshot user)
{
userName = user.value['Name'];
setState(() {
print(userName);
});
});
});
https://dart.dev/codelabs/async-await

How to pass data to the Typeahead from firestore in flutter

I'm a beginner in a flutter, in the flutter project I used flutter_typeahead package but I was not able to execute this code.
I want to search my items on the base of the input given by the user. I write the following code with the Typoahead
Anyone who tells me what is wrong in my code
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:fmiantrader/SearchService.dart';
import 'SearchService.dart';
class Serchitemsbymod extends StatefulWidget {
static String id='serchitemsbymod';
#override
_SerchitemsbymodState createState() => _SerchitemsbymodState();
}
class _SerchitemsbymodState extends State<Serchitemsbymod> {
List<String> store=[];
var q=[];
var t=[];
SearchService _searchService=SearchService();
List<DocumentSnapshot> search=<DocumentSnapshot>[];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Mian Traders'),
),
body: Padding(
padding: const EdgeInsets.all(30.0),
child: TypeAheadField(
textFieldConfiguration: TextFieldConfiguration(
autofocus: true,
style: DefaultTextStyle.of(context).style.copyWith(
fontStyle: FontStyle.italic
),
decoration: InputDecoration(
border: OutlineInputBorder()
)
),
suggestionsCallback: (pattern) async {
return await _getsearch().getSuggestion(pattern);
},
itemBuilder: (context, suggestion) {
return ListTile(
leading: Icon(Icons.shopping_cart),
title: Column(
children: <Widget>[
Text(suggestion['A']),
Text(suggestion['B']),
],
),
subtitle: Text('${suggestion['C']}'),
);
},
onSuggestionSelected: (suggestion) {
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => ProductPage(product: suggestion)
// ));
},
),
),
);
}
_getsearch()async{
List<DocumentSnapshot> data=await _searchService.getSearch();
setState(() {
search=data;
});
}
}
My SearchService classcode is this
import 'package:cloud_firestore/cloud_firestore.dart';
class SearchService {
Firestore _firestore = Firestore.instance;
String ref='items';
Future<List<DocumentSnapshot>> getSearch() =>
_firestore.collection(ref)
.getDocuments()
.then((snaps){
return snaps.documents;
});
Future<List<DocumentSnapshot>> getSuggestion(String suggestion) =>
_firestore.collection(ref)
.where('items', isEqualTo: suggestion)
.getDocuments()
.then((snap) {
return snap.documents;
});
}
My firestore data is
when I start searching
I got the following error
You are calling _getsearch() but that doesn't return anything.
I think you just need to call getSuggestion(pattern) on the SearchService you've instantiated:
suggestionsCallback: (pattern) async {
return await _searchService.getSuggestion(pattern);
},
It's quite possible that you'll need some mapping in either that getSuggestion() function, or in the itemBuilder to go from a DocumentSnapshot to an object where you can call ['A'] or ['B'] on.
I get the following solution in my case
My SearchServices class is
import 'package:cloud_firestore/cloud_firestore.dart';
class SearchService {
Firestore _firestore = Firestore.instance;
String ref = 'items';
Future<List<DocumentSnapshot>> getSearch() async =>
await _firestore.collection(ref).getDocuments().then((snaps) {
return snaps.documents;
});
Future<List<DocumentSnapshot>> getuserSearch() async =>
await _firestore.collection('users').getDocuments().then((snaps) {
return snaps.documents;
});
Future<List<DocumentSnapshot>> getSuggestion(String suggestion) async =>
await _firestore
.collection(ref)
.where('items', isEqualTo: suggestion)
.getDocuments()
.then((snap) {
return snap.documents;
});
}
and my Typohead class is
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:fmiantrader/SearchService.dart';
import 'SearchService.dart';
class Serchitemsbymod extends StatefulWidget {
static String id = 'serchitemsbymod';
#override
_SerchitemsbymodState createState() => _SerchitemsbymodState();
}
class _SerchitemsbymodState extends State<Serchitemsbymod> {
SearchService _searchService = SearchService();
List<Map> search = <Map>[];
#override
void initState() {
getDocs();
super.initState();
}
Future getDocs() async {
search =
(await _searchService.getSearch()).map((item) => item.data).toList();
setState(() {});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Mian Traders'),
),
body: Padding(
padding: const EdgeInsets.all(30.0),
child:TypeAheadField(
textFieldConfiguration: TextFieldConfiguration(
autofocus: false,
textAlign: TextAlign.center,
style:
TextStyle(
color: Colors.black,
fontSize: 15.0
),
decoration: InputDecoration(border: OutlineInputBorder(
borderSide: BorderSide(color:Colors.blueAccent,width: 1.0),
borderRadius: BorderRadius.circular(32.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent),
borderRadius: BorderRadius.circular(32.0)
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueAccent,width: 2.0),
borderRadius: BorderRadius.circular(32.0),
),
hintText: ('Enter the Name of item'),
hintStyle: TextStyle(
fontSize: 15.0,
),
)),
suggestionsCallback: (pattern) {
return search.where(
(doc) => jsonEncode(doc)
.toLowerCase()
.contains(pattern.toLowerCase()),
);
},
itemBuilder: (context, suggestion) {
return Card(
color: Colors.lightBlueAccent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
elevation: 6.0,
child: Center(
child: Column(
children: <Widget>[
Text(suggestion['A'],
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
),),
Text(suggestion['B'],
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
)),
Text(suggestion['C'],
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
),)
],
),
),
);
},
onSuggestionSelected: (suggestion) {
final map = jsonDecode(suggestion);
},
),
),
);
}
}

Resources