Related
I am trying to implement a google sign for my application using firebase.
when i press on google sign in button a pop up window appear to select the mail id when i press on my mail id i am not redirecting to LoggedInWidgit() page.
I am not getting where my code is not working
home_page.dart
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:note_app_demo/screens/login_page.dart';
import 'package:note_app_demo/utilities/logged_in_widgit.dart';
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) => Scaffold(
body: StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.hasData) {
return LogedInWidgit();
} else if (snapshot.hasError) {
return Center(
child: Text('Something went Wrong!'),
);
} else {
return LOGIN_PAGE();
}
},
),
);
}
logged_in_widgit.dart
import 'package:flutter/material.dart';
import 'package:note_app_demo/utilities/scaffold.dart';
import 'package:firebase_auth/firebase_auth.dart';
class LogedInWidgit extends StatelessWidget {
const LogedInWidgit({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final user = FirebaseAuth.instance.currentUser!;
return Scaffold(
appBar: AppBar(
title: Text('Logged In'),
centerTitle: true,
actions: [
TextButton(
onPressed: () {},
child: Text('Logout'),
)
],
),
body: Container(
alignment: Alignment.center,
color: Colors.blueGrey.shade900,
child: Column(
children: [
Text(
'Profile',
style: TextStyle(fontSize: 24),
),
SizedBox(
height: 32,
),
CircleAvatar(
radius: 40,
backgroundImage: NetworkImage(user.photoURL!),
),
SizedBox(
height: 8,
),
Text(
'Name: ' + user.displayName!,
style: TextStyle(color: Colors.white, fontSize: 16),
),
SizedBox(
height: 8,
)
],
),
),
);
}
}
main.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:note_app_demo/provider/google_sign_in.dart';
import 'package:note_app_demo/screens/landing_page.dart';
import 'package:flutter/services.dart';
import 'package:note_app_demo/screens/login_page.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:provider/provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) => ChangeNotifierProvider(
create: (context) => GoogleSignInProvider(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Studiac',
home: LOGIN_PAGE(),
),
);
}
login_page.dart
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:note_app_demo/provider/google_sign_in.dart';
import 'package:note_app_demo/screens/landing_page.dart';
import 'package:note_app_demo/button.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart';
class LOGIN_PAGE extends StatelessWidget {
const LOGIN_PAGE({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: ElevatedButton.icon(
icon: FaIcon(
Icons.email,
color: Colors.blue,
),
label: Text('Sign Up with Email'),
onPressed: () {},
style: ElevatedButton.styleFrom(
primary: Colors.tealAccent,
onPrimary: Colors.black,
minimumSize: Size(double.infinity, 50),
),
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: ElevatedButton.icon(
icon: FaIcon(
FontAwesomeIcons.google,
color: Colors.red,
),
label: Text('Sign Up with Google'),
onPressed: () {
final provider = Provider.of<GoogleSignInProvider>(context,
listen: false);
provider.googleLogin();
},
style: ElevatedButton.styleFrom(
primary: Colors.tealAccent,
onPrimary: Colors.black,
minimumSize: Size(double.infinity, 50),
),
),
),
],
),
),
),
);
}
}
google_sign_in.dart
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:firebase_auth/firebase_auth.dart';
class GoogleSignInProvider extends ChangeNotifier {
final googleSignIn = GoogleSignIn();
GoogleSignInAccount? _user;
//getter to get google sign in
GoogleSignInAccount get user => _user!;
Future googleLogin() async {
try {
final googleUser = await googleSignIn.signIn();
if (googleUser == null) return;
_user = googleUser;
final googleAuth = await googleUser.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken, idToken: googleAuth.idToken);
await FirebaseAuth.instance.signInWithCredential(credential);
} catch (e) {
print(e.toString());
}
notifyListeners();
}
Future logout() async {
await googleSignIn.disconnect();
FirebaseAuth.instance.signOut();
}
}
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');
});
});
}
}
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;
}
https://i.stack.imgur.com/9k5MB.png
I am new to flutter and I'm working on social distancing app in flutter. I wanted to push the uuid of bluetooth devices discovered to the firestore can someone please help me in doing this
I can print out the discovered devices in my app and i can get rssi uuid txpower
but as rssi keeps varying and scanning happens continuously the devices get pushed into firestore multiple times
i wanted UUID to be pushed into the firestore only once.
Nearby.dart
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:beacon_broadcast/beacon_broadcast.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'homescreen.dart';
import 'material.dart';
class BlueApp extends StatefulWidget {
#override
_BlueAppState createState() => _BlueAppState();
}
BeaconBroadcast beaconBroadcast = BeaconBroadcast();
BeaconStatus _isTransmissionSupported;
bool _isAdvertising = false;
StreamSubscription<bool> _isAdvertisingSubscription;
final databaseReference=Firestore.instance;
String UUID = "3E4D7TJ9008";
void createRecord(String usid) async {
await databaseReference.collection("users")
.document("1")
.setData({
'uuid':usid
});
print('senddddddddingggggg');
DocumentReference ref = await databaseReference.collection("users")
.add({
'uuid':usid
});
print(ref.documentID);
}
class _BlueAppState extends State<BlueApp> {
static const UUID = '39ED98FF';
static const MAJOR_ID = 1;
static const MINOR_ID = 100;
static const TRANSMISSION_POWER = -59;
static const IDENTIFIER = 'com.example.myDeviceRegion';
static const LAYOUT = BeaconBroadcast.ALTBEACON_LAYOUT;
static const MANUFACTURER_ID = 0x0118;
void initState() {
// TODO: implement initState
super.initState();
FlutterBlue.instance.state.listen((state) {
print("im in the init");
print(state);
if (state == BluetoothState.off) {
print("bluetooth is off");
} else if (state == BluetoothState.on) {
print("bluethooth on");
//print(device.id);
}
print("printing eacon");
});
beaconBroadcast.checkTransmissionSupported().then((isTransmissionSupported) {
setState(() {
_isTransmissionSupported = isTransmissionSupported;
print(_isTransmissionSupported);
});
});
_isAdvertisingSubscription =
beaconBroadcast.getAdvertisingStateChange().listen((isAdvertising) {
setState(() {
_isAdvertising = isAdvertising;
});
});
beaconBroadcast
.setUUID(UUID)
.setMajorId(MAJOR_ID)
.setMinorId(MINOR_ID)
.setTransmissionPower(-59)
.setIdentifier(IDENTIFIER)
.setLayout(LAYOUT)
.setManufacturerId(MANUFACTURER_ID)
.start();
if(_isAdvertising==true){
print('Beacon started Advertising');
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
color: Colors.lightBlue,
home: StreamBuilder<BluetoothState>(
stream: FlutterBlue.instance.state,
initialData: BluetoothState.turningOn,
builder: (c, snapshot) {
final state = snapshot.data;
print(state);
if (state == BluetoothState.on) {
print("BlueTooth is on");
return FindDevicesScreen();
}
print("BlueTooth is off");
return BluetoothOffScreen(state: state);
}),
);
}
}
class BluetoothOffScreen extends StatelessWidget {
const BluetoothOffScreen({Key key, this.state}) : super(key: key);
final BluetoothState state;
#override
Widget build(BuildContext context) {
_BlueAppState a=new _BlueAppState();
createRecord(UUID);
return Scaffold(
backgroundColor: Colors.lightBlue,
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.bluetooth_disabled,
size: 200.0,
color: Colors.white54,
),
Text(
'Bluetooth Adapter is ${state != null ? state.toString().substring(15) : 'not available'}.',
style: Theme.of(context)
.primaryTextTheme
.subhead
.copyWith(color: Colors.white),
),
],
),
),
);
}
}
class FindDevicesScreen extends StatefulWidget {
#override
_FindDevicesScreenState createState() => _FindDevicesScreenState();
}
class _FindDevicesScreenState extends State<FindDevicesScreen> {
#override
void initState() {
// TODO: implement initState
super.initState();
FlutterBlue.instance.startScan();
beaconBroadcast.checkTransmissionSupported().then((isTransmissionSupported) {
setState(() {
_isTransmissionSupported = isTransmissionSupported;
print(_isTransmissionSupported);
});
});
_isAdvertisingSubscription =
beaconBroadcast.getAdvertisingStateChange().listen((isAdvertising) {
setState(() {
_isAdvertising = isAdvertising;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Find Devices'),
),
body: RefreshIndicator(
onRefresh: () =>
FlutterBlue.instance.startScan(),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
StreamBuilder<List<BluetoothDevice>>(
stream: Stream.periodic(Duration(seconds: 4))
.asyncMap((_) => FlutterBlue.instance.connectedDevices),
initialData: [],
builder: (c, snapshot) => Column(
children: snapshot.data
.map((d) => ListTile(
title: Text(d.name),
subtitle: Text(d.id.toString()),
trailing: StreamBuilder<BluetoothDeviceState>(
stream: d.state,
initialData: BluetoothDeviceState.disconnected,
builder: (c, snapshot) {
print('entering if');
if (true) {
print('id----------------------------------------------did');
}
return Text(snapshot.data.toString());
},
),
))
.toList(),
),
),
StreamBuilder<List<ScanResult>>(
stream: FlutterBlue.instance.scanResults,
initialData: [],
builder: (c, snapshot) => Column(
children: snapshot.data
.map(
(r) => Card(
child: ScanResultTile(
result: r,
onTap: () => Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
return null;
})),
),
),
)
.toList(),
),
),
],
),
),
),
);
}
}
material.dart
import 'package:flutter_blue/flutter_blue.dart';
import 'nearby.dart';
class ScanResultTile extends StatelessWidget {
const ScanResultTile({Key key, this.result, this.onTap}) : super(key: key);
final ScanResult result;
final VoidCallback onTap;
Widget _buildTitle(BuildContext context) {
if (result.device.name.length > 0) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
result.device.name,
overflow: TextOverflow.ellipsis,
),
Text(
result.device.id.toString(),
style: Theme.of(context).textTheme.caption,
),
// _buildAdvRow(
// context, 'Distance of the device',(result.rssi!=null && result.advertisementData.txPowerLevel!=null)?"${getDistance(result.rssi,result.advertisementData.txPowerLevel)}":"N/A" ),
],
);
} else {
return Text(result.device.id.toString());
}
}
Widget _buildAdvRow(BuildContext context, String title, String value) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(title, style: Theme.of(context).textTheme.caption),
SizedBox(
width: 12.0,
),
Expanded(
child: Text(
value,
style: Theme.of(context)
.textTheme
.caption
.apply(color: Colors.black),
softWrap: true,
),
),
],
),
);
}
String getNiceHexArray(List<int> bytes) {
return '[${bytes.map((i) => i.toRadixString(16).padLeft(2, '0')).join(', ')}]'
.toUpperCase();
}
int getDistance(int rssi, int txPower) {
print("rssi");
print(rssi);
return 10 ^ ((txPower - rssi) / (10 * 2)).round();
}
#override
Widget build(BuildContext context) {
print("rssi");
print(result.rssi);
print("Transmit power");
print(result.advertisementData.txPowerLevel);
// print(result.device.name);
print(result);
// if((getDistance(result.rssi,result.advertisementData.txPowerLevel))<=2)
// {
// createRecord(result.advertisementData.serviceUuids.iterator.moveNext().toString());
// }
return ExpansionTile(
title: _buildTitle(context),
leading: Column(
children: <Widget>[
Text("Tap for more...",style: TextStyle(fontSize: 10.0,color: Colors.lightBlueAccent),)
],
),
children: <Widget>[
_buildAdvRow(
context, 'Distance of the device',(result.rssi!=null && result.advertisementData.txPowerLevel!=null)?"${getDistance(result.rssi,result.advertisementData.txPowerLevel)}":"N/A" ),
_buildAdvRow(context, 'Tx Power Level',
'${result.advertisementData.txPowerLevel ?? 'N/A'}'),
_buildAdvRow(
context,
'Service UUIDs',
(result.advertisementData.serviceUuids.isNotEmpty)? result.advertisementData.serviceUuids.join(', ').toUpperCase(): 'N/A'),
],
);
}
}
class ServiceTile extends StatelessWidget {
final BluetoothService service;
final List<CharacteristicTile> characteristicTiles;
const ServiceTile({Key key, this.service, this.characteristicTiles})
: super(key: key);
#override
Widget build(BuildContext context) {
if (characteristicTiles.length > 0) {
return ExpansionTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Service'),
Text('0x${service.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context)
.textTheme
.body1
.copyWith(color: Theme.of(context).textTheme.caption.color))
],
),
children: characteristicTiles,
);
} else {
return ListTile(
title: Text('Service'),
subtitle:
Text('0x${service.uuid.toString().toUpperCase().substring(4, 8)}'),
);
}
}
}
class CharacteristicTile extends StatelessWidget {
final BluetoothCharacteristic characteristic;
final List<DescriptorTile> descriptorTiles;
final VoidCallback onReadPressed;
final VoidCallback onWritePressed;
final VoidCallback onNotificationPressed;
const CharacteristicTile(
{Key key,
this.characteristic,
this.descriptorTiles,
this.onReadPressed,
this.onWritePressed,
this.onNotificationPressed})
: super(key: key);
#override
Widget build(BuildContext context) {
return StreamBuilder<List<int>>(
stream: characteristic.value,
initialData: characteristic.lastValue,
builder: (c, snapshot) {
final value = snapshot.data;
return ExpansionTile(
title: ListTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Characteristic'),
Text(
'0x${characteristic.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context).textTheme.body1.copyWith(
color: Theme.of(context).textTheme.caption.color))
],
),
subtitle: Text(value.toString()),
contentPadding: EdgeInsets.all(0.0),
),
children: descriptorTiles,
);
},
);
}
}
class DescriptorTile extends StatelessWidget {
final BluetoothDescriptor descriptor;
final VoidCallback onReadPressed;
final VoidCallback onWritePressed;
const DescriptorTile(
{Key key, this.descriptor, this.onReadPressed, this.onWritePressed})
: super(key: key);
#override
Widget build(BuildContext context) {
return ListTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Descriptor'),
Text('0x${descriptor.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context)
.textTheme
.body1
.copyWith(color: Theme.of(context).textTheme.caption.color))
],
),
subtitle: StreamBuilder<List<int>>(
stream: descriptor.value,
initialData: descriptor.lastValue,
builder: (c, snapshot) => Text(snapshot.data.toString()),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(
Icons.file_download,
color: Theme.of(context).iconTheme.color.withOpacity(0.5),
),
onPressed: onReadPressed,
),
IconButton(
icon: Icon(
Icons.file_upload,
color: Theme.of(context).iconTheme.color.withOpacity(0.5),
),
onPressed: onWritePressed,
)
],
),
);
}
}
class AdapterStateTile extends StatelessWidget {
const AdapterStateTile({Key key, #required this.state}) : super(key: key);
final BluetoothState state;
#override
Widget build(BuildContext context) {
return Container(
color: Colors.redAccent,
child: ListTile(
title: Text(
'Bluetooth adapter is ${state.toString().substring(15)}',
style: Theme.of(context).primaryTextTheme.subhead,
),
trailing: Icon(
Icons.error,
color: Theme.of(context).primaryTextTheme.subhead.color,
),
),
);
}
}```
To avoid adding it additional times there are two altenatives.
Alternative 1:
Index the uuid field, as this will allow you to query over this field
Before writing query for documents with this uuid
Write only if the response is empty
This alternative has the advantage that no changes need to be done on firestore and minimun changes on the code, however will have the disadvantage that each write attempt will be preceeded by a read and reads are billed.
Alternative 2:
Change the data structucture on Firestore so that the UUID is the document ID
This has the advantage that the writes won't be preceeded by a read therefore its cheaper on firestore costs. However it needs more code edition and will need to change the data stucture.
for the code the main change is on the following method:
void createRecord(String usid) async {
await databaseReference.collection("users")
.document(usid)
.setData({
'uuid':usid
});
print('senddddddddingggggg');
DocumentReference ref = await databaseReference.collection("users")
.document(usid)
.setData({
'uuid':usid
});
print(ref.documentID);
}
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(),