Download image with url but it doesn't show in galery - firebase

I'm using the code from the example of this dependencie image_downloader: ^0.31.0, the problem is that it doesn't show any error but the image doesn't go to the galery.
This screen is to show the images from firestore and create listtyle that when the user clicks the image is suposed to download it.
import 'dart:io';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:image_downloader/image_downloader.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:pap_test/upload/upload_resumos_screen.dart';
class DownloadScreen extends StatefulWidget {
const DownloadScreen({Key? key}) : super(key: key);
static const routeName = '/downlaod-resumos';
#override
State<DownloadScreen> createState() => _DownloadScreenState();
}
class _DownloadScreenState extends State<DownloadScreen> {
String _message = "";
String _path = "";
String _size = "";
String _mimeType = "";
File? _imageFile;
int _progress = 0;
String query = '1';
CollectionReference _firebaseFirestore =
FirebaseFirestore.instance.collection('images');
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Resumos'),
),
body: StreamBuilder<QuerySnapshot>(
stream: _firebaseFirestore.snapshots().asBroadcastStream(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
if (snapshot.data!.docs
.where((QueryDocumentSnapshot<Object?>
element) =>
element['disciplina']
.toString()
.toLowerCase()
.contains(query.toLowerCase()))
.isEmpty) {
return Center(
child: Text(
'Por aqui está muito lento, carrega no botão e publica um resumo.',
style: Theme.of(context).textTheme.headline5,
textAlign: TextAlign.center,
),
);
} else {
return ListView(
children: [
...snapshot.data!.docs
.where((QueryDocumentSnapshot<Object?>
element) =>
element['disciplina']
.toString()
.toLowerCase()
.contains(query.toLowerCase()))
.map(
(QueryDocumentSnapshot<Object?> data) {
final String descricao = data.get('descricao');
final _image = data['url'];
return ListTile(
onTap: () {
_downloadImage(_image);
},
leading: CircleAvatar(
backgroundImage: NetworkImage(_image),
),
title: Text(
descricao.toString(),
style: Theme.of(context).textTheme.headline5,
),
);
},
)
],
);
}
}
},
),
);
}
Future<void> _downloadImage(
String url, {
AndroidDestinationType? destination,
bool whenError = false,
String? outputMimeType,
}) async {
String? fileName;
String? path;
int? size;
String? mimeType;
try {
String? imageId;
if (whenError) {
imageId = await ImageDownloader.downloadImage(url,
outputMimeType: outputMimeType)
.catchError((error) {
if (error is PlatformException) {
String? path = "";
if (error.code == "404") {
print("Not Found Error.");
} else if (error.code == "unsupported_file") {
print("UnSupported FIle Error.");
path = error.details["unsupported_file_path"];
}
setState(() {
_message = error.toString();
_path = path ?? '';
});
}
print(error);
}).timeout(Duration(seconds: 10), onTimeout: () {
print("timeout");
return;
});
} else {
if (destination == null) {
imageId = await ImageDownloader.downloadImage(
url,
outputMimeType: outputMimeType,
);
} else {
imageId = await ImageDownloader.downloadImage(
url,
destination: destination,
outputMimeType: outputMimeType,
);
}
}
if (imageId == null) {
return;
}
fileName = await ImageDownloader.findName(imageId);
path = await ImageDownloader.findPath(imageId);
size = await ImageDownloader.findByteSize(imageId);
mimeType = await ImageDownloader.findMimeType(imageId);
} on PlatformException catch (error) {
setState(() {
_message = error.message ?? '';
});
return;
}
if (!mounted) return;
setState(
() {
var location = Platform.isAndroid ? "Directory" : "Photo Library";
_message = 'Saved as "$fileName" in $location.\n';
_size = 'size: $size';
_mimeType = 'mimeType: $mimeType';
_path = path ?? '';
if (!_mimeType.contains("video")) {
_imageFile = File(path!);
}
return;
},
);
}
}
This is what shows in the console after i click on the image
And this is the galery after i clicked

Related

Progress Indicator when firebase is retrieving data on chat - Flutter

I have a flutter project chat with firebase realtime database and when I open a chat with a user, firebase take 1-3 seconds to load the conversation.
So, I have to insert a progress indicator when firebase is retrieving data on chat opended.
This is the class:
class ChatView extends StatefulWidget {
const ChatView({
Key key,
#required this.itemId,
#required this.chatFlag,
#required this.buyerUserId,
#required this.sellerUserId,
}) : super(key: key);
final String itemId;
final String chatFlag;
final String buyerUserId;
final String sellerUserId;
// final String isOffer;
#override
_ChatViewState createState() => _ChatViewState();
}
enum ChatUserStatus { active, in_active, offline }
class _ChatViewState extends State<ChatView>
with SingleTickerProviderStateMixin, WidgetsBindingObserver {
AnimationController animationController;
DatabaseReference _messagesRef;
DatabaseReference _chatRef;
DatabaseReference _userPresence;
final bool _anchorToBottom = true;
FirebaseApp firebaseApp;
PsValueHolder psValueHolder;
String sessionId;
ChatHistoryRepository chatHistoryRepository;
NotificationRepository notiRepo;
UserUnreadMessageRepository userUnreadMessageRepository;
GalleryRepository galleryRepo;
ProductRepository productRepo;
GetChatHistoryProvider getChatHistoryProvider;
UserUnreadMessageProvider userUnreadMessageProvider;
ChatHistoryListProvider chatHistoryListProvider;
ItemDetailProvider itemDetailProvider;
GalleryProvider galleryProvider;
NotificationProvider notiProvider;
SyncChatHistoryParameterHolder holder;
GetChatHistoryParameterHolder getChatHistoryParameterHolder;
PsResource<ChatHistory> chatHistory;
String lastTimeStamp;
int lastAddedDateTimeStamp;
String status = '';
String itemId;
String receiverId;
String senderId;
String otherUserId;
ChatUserStatus isActive;
TextEditingController messageController = TextEditingController();
Future<FirebaseApp> configureDatabase() async {
WidgetsFlutterBinding.ensureInitialized();
final FirebaseApp app = await Firebase.initializeApp(
options: Platform.isIOS
? const FirebaseOptions(
appId: Config.iosGoogleAppId,
messagingSenderId: Config.iosGcmSenderId,
databaseURL: Config.iosDatabaseUrl,
projectId: Config.iosProjectId,
apiKey: Config.iosApiKey)
: const FirebaseOptions(
appId: Config.androidGoogleAppId,
apiKey: Config.androidApiKey,
projectId: Config.androidProjectId,
messagingSenderId: Config.androidGcmSenderId,
databaseURL: Config.androidDatabaseUrl,
),
);
return app;
}
#override
void initState() {
super.initState();
configureDatabase().then((FirebaseApp app) {
firebaseApp = app;
});
final FirebaseDatabase database = FirebaseDatabase(app: firebaseApp);
_messagesRef = database.reference().child('Message');
_chatRef = database.reference().child('Current_Chat_With');
_userPresence = database.reference().child('User_Presence');
if (database != null && database.databaseURL != null) {
database.setPersistenceEnabled(true);
database.setPersistenceCacheSizeBytes(10000000);
}
animationController =
AnimationController(duration: PsConfig.animation_duration, vsync: this);
WidgetsBinding.instance.addObserver(this);
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
// user returned to our app
} else if (state == AppLifecycleState.inactive) {
_chatRef.child(psValueHolder.loginUserId).remove();
// app is inactive
} else if (state == AppLifecycleState.paused) {
_chatRef.child(psValueHolder.loginUserId).remove();
// user is about quit our app temporally
} else if (state == AppLifecycleState.detached) {
// app suspended (not used in iOS)
}
}
#override
void dispose() {
super.dispose();
if (mounted) {
_chatRef.child(psValueHolder.loginUserId).remove();
_userPresence.child(psValueHolder.loginUserId).remove();
}
WidgetsBinding.instance.removeObserver(this);
Utils.isReachChatView = false;
}
Future<bool> resetUnreadMessageCount(
ChatHistoryListProvider chatHistoryListProvider,
PsValueHolder valueHolder,
UserUnreadMessageProvider userUnreadMessageProvider) async {
final ResetUnreadMessageParameterHolder resetUnreadMessageParameterHolder =
ResetUnreadMessageParameterHolder(
itemId: widget.itemId,
buyerUserId: widget.buyerUserId,
sellerUserId: widget.sellerUserId,
type: widget.chatFlag == PsConst.CHAT_FROM_BUYER
? PsConst.CHAT_TO_SELLER
: PsConst.CHAT_TO_BUYER);
final dynamic _returnData = await chatHistoryListProvider
.resetUnreadMessageCount(resetUnreadMessageParameterHolder.toMap());
if (_returnData == null) {
if (valueHolder.loginUserId != null && valueHolder.loginUserId != '') {
final UserUnreadMessageParameterHolder userUnreadMessageHolder =
UserUnreadMessageParameterHolder(
userId: valueHolder.loginUserId,
deviceToken: valueHolder.deviceToken);
userUnreadMessageProvider
.userUnreadMessageCount(userUnreadMessageHolder);
}
return true;
} else {
return false;
}
}
Future<void> _insertDataToFireBase(
String id,
bool isSold,
bool isUserBought,
String itemId,
String message,
int offerStatus,
String sendByUserId,
String sessionId,
int type,
) async {
final Message messages = Message();
messages.addedDate = Utils.getTimeStamp();
messages.id = id;
messages.isSold = isSold;
messages.isUserBought = isUserBought;
messages.itemId = itemId;
messages.message = message;
messages.offerStatus = offerStatus;
messages.sendByUserId = sendByUserId;
messages.sessionId = sessionId;
messages.type = type;
final String newkey = _messagesRef.child(sessionId).push().key;
messages.id = newkey;
_messagesRef
.child(sessionId)
.child(newkey)
.set(messages.toInsertMap(messages));
}
Future<void> _deleteDataToFireBase(
String id,
bool isSold,
String itemId,
String message,
String sendByUserId,
String sessionId,
) async {
final Message messages = Message();
messages.addedDate = Utils.getTimeStamp();
messages.id = id;
messages.isSold = isSold;
messages.itemId = itemId;
messages.message = message;
messages.sendByUserId = sendByUserId;
messages.sessionId = sessionId;
final String key =
_messagesRef.child(sessionId).child(id).remove().toString();
messages.id = key;
_messagesRef
.child(sessionId)
.child(key)
.set(messages.toDeleteMap(messages));
}
Future<void> _updateDataToFireBase(
int addedDate,
String id,
bool isSold,
bool isUserBought,
String itemId,
String message,
int offerStatus,
String sendByUserId,
String sessionId,
int type,
) async {
final Message messages = Message();
messages.id = id;
messages.isSold = isSold;
messages.isUserBought = isUserBought;
messages.itemId = itemId;
messages.message = message;
messages.offerStatus = offerStatus;
messages.sendByUserId = sendByUserId;
messages.sessionId = sessionId;
messages.type = type;
messages.addedDateTimeStamp = addedDate;
_messagesRef
.child(sessionId)
.child(messages.id)
.set(messages.toUpdateMap(messages));
}
Future<void> _insertSenderAndReceiverToFireBase(
String sessionId,
String itemId,
String receiverId,
String senderId,
String userName) async {
final Chat chat =
Chat(itemId: itemId, receiverId: receiverId, senderId: senderId);
_chatRef.child(senderId).set(chat.toMap(chat));
final ChatUserPresence chatUserPresence =
ChatUserPresence(userId: senderId, userName: userName);
_userPresence.child(senderId).set(chatUserPresence.toMap(chatUserPresence));
}
#override
Widget build(BuildContext context) {
const Widget _spacingWidget = SizedBox(
width: PsDimens.space10,
);
lastTimeStamp = null;
psValueHolder = Provider.of<PsValueHolder>(context);
chatHistoryRepository = Provider.of<ChatHistoryRepository>(context);
notiRepo = Provider.of<NotificationRepository>(context);
galleryRepo = Provider.of<GalleryRepository>(context);
productRepo = Provider.of<ProductRepository>(context);
userUnreadMessageRepository =
Provider.of<UserUnreadMessageRepository>(context);
if (psValueHolder.loginUserId != null) {
if (psValueHolder.loginUserId == widget.buyerUserId) {
sessionId =
Utils.sortingUserId(widget.sellerUserId, widget.buyerUserId);
otherUserId = widget.sellerUserId;
} else if (psValueHolder.loginUserId == widget.sellerUserId) {
sessionId =
Utils.sortingUserId(widget.buyerUserId, widget.sellerUserId);
otherUserId = widget.buyerUserId;
}
_insertSenderAndReceiverToFireBase(sessionId, widget.itemId, otherUserId,
psValueHolder.loginUserId, psValueHolder.loginUserName);
}
_chatRef.child(otherUserId).onValue.listen((Event event) {
if (event.snapshot.value == null) {
if (isActive == null || isActive != ChatUserStatus.offline && mounted) {
setState(() {
status = Utils.getString(context, 'chat_view__status_offline');
isActive = ChatUserStatus.offline;
});
}
} else {
itemId = event.snapshot.value['itemId'];
final String _receiverId = event.snapshot.value['receiver_id'];
if (_receiverId == psValueHolder.loginUserId &&
itemId == widget.itemId) {
if (isActive != ChatUserStatus.active && mounted) {
setState(() {
status = Utils.getString(context, 'chat_view__status_active');
isActive = ChatUserStatus.active;
});
}
} else {
if (isActive != ChatUserStatus.in_active && mounted) {
setState(() {
status = Utils.getString(context, 'chat_view__status_inactive');
isActive = ChatUserStatus.in_active;
});
}
}
}
});
Future<void> checkOfferStatus(ChatHistory chatHistory) async {
if (chatHistory != null &&
chatHistory.isOffer == PsConst.ONE &&
chatHistory.isAccept != PsConst.ONE) {
await getChatHistoryProvider
.getChatHistory(getChatHistoryParameterHolder);
}
}
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(0), // here the desired height
child: AppBar(
automaticallyImplyLeading: true,
systemOverlayStyle: SystemUiOverlayStyle(
statusBarIconBrightness: Utils.getBrightnessForAppBar(context),
),
iconTheme: Theme.of(context)
.iconTheme
.copyWith(color: PsColors.textPrimaryColor),
title: Text(
status,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline6.copyWith(
fontWeight: FontWeight.bold,
color: PsColors.white),
),
backgroundColor: PsColors.mainColor,
bottomOpacity: 0.0,
elevation: 0.0)),
body: PsWidgetWithMultiProvider(
child: MultiProvider(
providers: <SingleChildWidget>[
ChangeNotifierProvider<ItemDetailProvider>(
lazy: false,
create: (BuildContext context) {
itemDetailProvider = ItemDetailProvider(
repo: productRepo, psValueHolder: psValueHolder);
final String loginUserId =
Utils.checkUserLoginId(psValueHolder);
itemDetailProvider.loadProduct(widget.itemId, loginUserId);
return itemDetailProvider;
}),
ChangeNotifierProvider<UserUnreadMessageProvider>(
lazy: false,
create: (BuildContext context) {
userUnreadMessageProvider = UserUnreadMessageProvider(
repo: userUnreadMessageRepository);
return userUnreadMessageProvider;
}),
ChangeNotifierProvider<ChatHistoryListProvider>(
lazy: false,
create: (BuildContext context) {
chatHistoryListProvider =
ChatHistoryListProvider(repo: chatHistoryRepository);
resetUnreadMessageCount(chatHistoryListProvider,
psValueHolder, userUnreadMessageProvider);
return chatHistoryListProvider;
}),
ChangeNotifierProvider<NotificationProvider>(
lazy: false,
create: (BuildContext context) {
notiProvider = NotificationProvider(
repo: notiRepo, psValueHolder: psValueHolder);
return notiProvider;
}),
ChangeNotifierProvider<GalleryProvider>(
lazy: false,
create: (BuildContext context) {
galleryProvider = GalleryProvider(
repo: galleryRepo,
);
return galleryProvider;
}),
ChangeNotifierProvider<GetChatHistoryProvider>(
lazy: false,
create: (BuildContext context) {
getChatHistoryProvider =
GetChatHistoryProvider(repo: chatHistoryRepository);
getChatHistoryParameterHolder = GetChatHistoryParameterHolder(
itemId: widget.itemId,
buyerUserId: widget.buyerUserId,
sellerUserId: widget.sellerUserId);
getChatHistoryProvider
.getChatHistory(getChatHistoryParameterHolder);
return getChatHistoryProvider;
}),
],
child: Consumer<ItemDetailProvider>(builder:
(BuildContext context, ItemDetailProvider itemDetailProvider,
Widget child) {
if (itemDetailProvider.itemDetail != null &&
itemDetailProvider.itemDetail.data != null) {
return Container(
color: Utils.isLightMode(context)
? Colors.grey[100]
: Colors.grey[900],
child: Column(
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: Container(
alignment: Alignment.topCenter,
width: double.infinity,
child: ItemInfoWidget(
insertDataToFireBase: _insertDataToFireBase,
sessionId: sessionId,
itemData: itemDetailProvider.itemDetail.data,
sendByUserId: psValueHolder.loginUserId ?? '',
chatFlag: widget.chatFlag,
buyerUserId: widget.buyerUserId,
sellerUserId: widget.sellerUserId,
chatHistoryProvider: getChatHistoryProvider,
isOffer:
(getChatHistoryProvider.chatHistory.data !=
null &&
getChatHistoryProvider
.chatHistory.data.id !=
'')
? getChatHistoryProvider
.chatHistory.data.isOffer
: '0',
isUserOnline: isActive == ChatUserStatus.active
? PsConst.ONE
: PsConst.ZERO,
)
)),
Flexible(
child: Container(
margin:
const EdgeInsets.only(bottom: PsDimens.space12),
child: FirebaseAnimatedList(
key: ValueKey<bool>(_anchorToBottom),
query: _messagesRef
.child(sessionId)
.orderByChild('itemId')
.equalTo(widget.itemId),
reverse: _anchorToBottom,
sort: _anchorToBottom
? (DataSnapshot a, DataSnapshot b) {
return b.value['addedDate']
.toString()
.compareTo(
a.value['addedDate'].toString());
}
: null,
itemBuilder: (BuildContext context,
DataSnapshot snapshot,
Animation<double> animation,
int index) {
print('- - - - - - - /nIndex : $index');
bool isSameDate = false;
final Message messages =
Message().fromMap(snapshot.value);
final String chatDateString =
Utils.convertTimeStampToDate(
messages.addedDateTimeStamp);
if (index == 0 || lastTimeStamp == null) {
lastTimeStamp = chatDateString;
lastAddedDateTimeStamp =
messages.addedDateTimeStamp;
}
final DateTime msgDate =
Utils.getDateOnlyFromTimeStamp(
messages.addedDateTimeStamp);
final DateTime lastDate =
Utils.getDateOnlyFromTimeStamp(
lastAddedDateTimeStamp);
if (lastTimeStamp == chatDateString ||
msgDate.compareTo(lastDate) >= 0) {
isSameDate = true;
} else {
isSameDate = false;
}
final Widget _chatCell =
_ChatPageWidget(
buyerUserId: widget.buyerUserId,
sellerUserId: widget.sellerUserId,
chatFlag: widget.chatFlag,
chatHistoryProvider: getChatHistoryProvider,
chatHistoryParameterHolder:
getChatHistoryParameterHolder,
messageObj: messages,
itemDetail:
itemDetailProvider.itemDetail.data,
psValueHolder: psValueHolder,
updateDataToFireBase: _updateDataToFireBase,
insertDataToFireBase: _insertDataToFireBase,
deleteDataToFireBase: _deleteDataToFireBase,
checkOfferStatus: checkOfferStatus,
index: index,
isUserOnline:
isActive == ChatUserStatus.active
? PsConst.ONE
: PsConst.ZERO,
);
Widget _dateWidget;
if (!isSameDate) {
_dateWidget = Container(
margin: const EdgeInsets.only(
top: PsDimens.space8,
bottom: PsDimens.space8),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: <Widget>[
_spacingWidget,
const Expanded(
child: Divider(
height: PsDimens.space1,
color: Colors.black54),
),
_spacingWidget,
Container(
padding: const EdgeInsets.all(
PsDimens.space4),
decoration: BoxDecoration(
color: Colors.black54,
borderRadius:
BorderRadius.circular(
PsDimens.space8)),
child: Text(
lastTimeStamp,
style: Theme.of(context)
.textTheme
.caption
.copyWith(color: Colors.white),
),
),
_spacingWidget,
const Expanded(
child: Divider(
height: PsDimens.space1,
color: Colors.black54),
),
_spacingWidget,
],
),
);
lastTimeStamp = chatDateString;
lastAddedDateTimeStamp =
messages.addedDateTimeStamp;
}
if (msgDate.compareTo(lastDate) >= 0) {
lastTimeStamp = chatDateString;
lastAddedDateTimeStamp =
messages.addedDateTimeStamp;
}
return isSameDate
? _chatCell
: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
_chatCell,
_dateWidget,
],
);
},
),
),
),
],
),
);
} else {
return Container();
}
}))),
);
}
}
Can you suggest me a solution?
Flutter version 2.5.3
Implement a FutureBuilder like this (preferably in the main.dart where you initialize Firebase):
return FutureBuilder(
// Initialize FlutterFire:
future: _initialization,
builder: (context, snapshot) {
// Check for errors
if (snapshot.hasError) {
return SomethingWentWrong();
}
// Once complete, show your application
if (snapshot.connectionState == ConnectionState.done) {
return MyAwesomeApp();
}
// Otherwise, show something whilst waiting for initialization to complete
return Loading();
},
);
For the Loading(); you can either make your own custom widget or just render a CircularProgressIndicator(). Here you can find out how to configure it.

Failed assertion: line 133 pos 12: 'file.absolute.existsSync()': is not true

Hello I am a beginner and I am trying to record audio and upload it to firebase but I am facing an error which probably says that file does not exists.
Currently Flutter Audio Recorder is reading audio data but when Audio Recorder is set to stop and the process of uploading begins then the error is generated. I have checked file existence using existsSync() method which returned false
Kindly help me out in this. Here is my code
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:avatar_glow/avatar_glow.dart';
import 'package:flutter_audio_recorder/flutter_audio_recorder.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:path_provider/path_provider.dart';
class HomeView extends StatefulWidget {
#override
_HomeViewState createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
bool _isRecording;
String _convertedText;
String _fileName;
String _filePath;
FlutterAudioRecorder _audioRecorder;
#override
void initState() {
super.initState();
_isRecording = false;
_fileName = "";
_convertedText = "Press the Record button to convert text";
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Urdu Speech to Text Converter"),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: AvatarGlow(
animate: _isRecording,
glowColor: Theme
.of(context)
.primaryColor,
endRadius: 75.0,
duration: const Duration(milliseconds: 2000),
repeatPauseDuration: const Duration(milliseconds: 100),
repeat: true,
child: FloatingActionButton(
onPressed: _onRecordButtonPressed,
child: Icon(_isRecording ? Icons.mic : Icons.mic_none),
),
),
body: SingleChildScrollView(
reverse: true,
child: Container(
padding: const EdgeInsets.fromLTRB(30.0, 30.0, 30.0, 150.0),
child: Text(_convertedText)
),
),
);
}
Future<void> _uploadFile() async {
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
try {
await firebaseStorage
.ref()
.child(_fileName)
.putFile(File(_filePath));
} catch (error) {
print('Error occured while uplaoding to Firebase ${error.toString()}');
// Scaffold.of(context).showSnackBar(
// SnackBar(
// content: Text('Error occured while uplaoding'),
// ),
// );
}
}
Future<void> _onRecordButtonPressed() async {
if (_isRecording) {
_audioRecorder.stop();
_isRecording = false;
File(_filePath).existsSync() ? _uploadFile() : print("*************** File Doesn't Exists **************");
} else {
_isRecording = true;
await _startRecording();
}
setState(() {});
}
Future<void> _startRecording() async {
final bool hasRecordingPermission =
await FlutterAudioRecorder.hasPermissions;
if (hasRecordingPermission) {
Directory directory = await getApplicationDocumentsDirectory();
String filepath = directory.path +
'/' +
DateTime
.now()
.millisecondsSinceEpoch
.toString() +
'.wav';
_audioRecorder =
FlutterAudioRecorder(filepath, audioFormat: AudioFormat.WAV);
await _audioRecorder.initialized;
_audioRecorder.start();
_filePath = filepath;
_fileName = _filePath.substring(_filePath.lastIndexOf('/') + 1, _filePath.length);
_convertedText = _fileName;
setState(() {});
} else {
print("*************************** No Permissions *****************************");
}
}
}

Error appears only the first call, once the screen opens again, the error disappears,

As per the screenshot once I open the screen it gives me the error "The getter 'email' was called on null." but if I just click back button, then open the screen again, it works well without any error,
the purpose of the screen is the account owner see the notes that was sent to him from the admin account
This is the error appears only one time after opening the app
Here the same screen without any error
Here is the codes in dart where the tap to screen exists
import 'package:flutter/cupertino.dart' show CupertinoIcons;
import 'package:flutter/material.dart';
import 'package:notification_permissions/notification_permissions.dart';
import 'package:provider/provider.dart';
import 'package:rate_my_app/rate_my_app.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../../app.dart';
import '../../common/config.dart';
import '../../common/constants.dart';
import '../../common/tools.dart';
import '../../generated/l10n.dart';
import '../../models/index.dart' show AppModel, User, UserModel, WishListModel;
import '../../routes/flux_navigate.dart';
import '../../screens/blogs/post_screen.dart';
import '../../services/index.dart';
import '../../widgets/common/webview.dart';
import '../custom/smartchat.dart';
import '../index.dart';
import '../users/user_point.dart';
import 'currencies.dart';
import 'language.dart';
import 'notification.dart';
import '../../common/config.dart' as config;
import 'package:cespohm/screens/bywaleed/booking_admin_screen.dart';
import 'package:cespohm/screens/bywaleed/docor_note_tap.dart';
import 'package:cespohm/screens/bywaleed/user_search_new_screen.dart';
import 'package:cespohm/screens/bywaleed/doctor_notes_user_screen.dart';
class SettingScreen extends StatefulWidget {
final List<dynamic> settings;
final String background;
final User user;
final VoidCallback onLogout;
final bool showChat;
SettingScreen({
this.user,
this.onLogout,
this.settings,
this.background,
this.showChat,
});
#override
_SettingScreenState createState() {
return _SettingScreenState();
}
}
class _SettingScreenState extends State<SettingScreen>
with
TickerProviderStateMixin,
WidgetsBindingObserver,
AutomaticKeepAliveClientMixin<SettingScreen> {
#override
bool get wantKeepAlive => true;
final bannerHigh = 150.0;
bool enabledNotification = true;
final RateMyApp _rateMyApp = RateMyApp(
// rate app on store
minDays: 7,
minLaunches: 10,
remindDays: 7,
remindLaunches: 10,
googlePlayIdentifier: kStoreIdentifier['android'],
appStoreIdentifier: kStoreIdentifier['ios']);
void showRateMyApp() {
_rateMyApp.showRateDialog(
context,
title: S.of(context).rateTheApp,
// The dialog title.
message: S.of(context).rateThisAppDescription,
// The dialog message.
rateButton: S.of(context).rate.toUpperCase(),
// The dialog "rate" button text.
noButton: S.of(context).noThanks.toUpperCase(),
// The dialog "no" button text.
laterButton: S.of(context).maybeLater.toUpperCase(),
// The dialog "later" button text.
listener: (button) {
// The button click listener (useful if you want to cancel the click event).
switch (button) {
case RateMyAppDialogButton.rate:
break;
case RateMyAppDialogButton.later:
break;
case RateMyAppDialogButton.no:
break;
}
return true; // Return false if you want to cancel the click event.
},
// Set to false if you want to show the native Apple app rating dialog on iOS.
dialogStyle: const DialogStyle(),
// Custom dialog styles.
// Called when the user dismissed the dialog (either by taping outside or by pressing the "back" button).
// actionsBuilder: (_) => [], // This one allows you to use your own buttons.
);
}
#override
void initState() {
super.initState();
Future.delayed(Duration.zero, () async {
await checkNotificationPermission();
});
_rateMyApp.init().then((_) {
// state of rating the app
if (_rateMyApp.shouldOpenDialog) {
showRateMyApp();
}
});
}
// #override
// void dispose() {
// Utils.setStatusBarWhiteForeground(false);
// super.dispose();
// }
Future<void> checkNotificationPermission() async {
if (!isAndroid || isIos) {
return;
}
try {
await NotificationPermissions.getNotificationPermissionStatus()
.then((status) {
if (mounted) {
setState(() {
enabledNotification = status == PermissionStatus.granted;
});
}
});
} catch (err) {
printLog('[Settings Screen] : ${err.toString()}');
}
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
checkNotificationPermission();
}
}
/// Render the Admin Vendor Menu
Widget renderVendorAdmin() {
if (!(widget.user != null ? widget.user.isVendor ?? false : false)) {
return Container();
}
return Card(
color: Theme.of(context).backgroundColor,
margin: const EdgeInsets.only(bottom: 2.0),
elevation: 0,
child: ListTile(
onTap: () {
final String langCode =
Provider.of<AppModel>(context, listen: false).langCode;
if (unsupportedLanguages.contains(langCode)) {
final snackBar = SnackBar(
content: Text(
S.of(context).thisFeatureDoesNotSupportTheCurrentLanguage),
duration: const Duration(seconds: 1),
);
Scaffold.of(context).showSnackBar(snackBar);
return;
}
FluxNavigate.push(
MaterialPageRoute(
builder: (context) =>
Services().widget.getAdminVendorScreen(context, widget.user),
),
forceRootNavigator: true,
);
},
leading: Icon(
Icons.dashboard,
size: 24,
color: Theme.of(context).accentColor,
),
title: Text(
S.of(context).vendorAdmin,
style: const TextStyle(fontSize: 16),
),
trailing: Icon(
Icons.arrow_forward_ios,
size: 18,
color: Theme.of(context).accentColor,
),
),
);
}
/// Render the custom profile link via Webview
/// Example show some special profile on the woocommerce site: wallet, wishlist...
Widget renderWebViewProfile() {
if (widget.user == null) {
return Container();
}
var base64Str = Utils.encodeCookie(widget.user.cookie);
var profileURL = '${serverConfig["url"]}/my-account?cookie=$base64Str';
return Card(
color: Theme.of(context).backgroundColor,
margin: const EdgeInsets.only(bottom: 2.0),
elevation: 0,
child: ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WebView(
url: profileURL, title: S.of(context).updateUserInfor),
),
);
},
leading: Icon(
CupertinoIcons.profile_circled,
size: 24,
color: Theme.of(context).accentColor,
),
title: Text(
S.of(context).updateUserInfor,
style: const TextStyle(fontSize: 16),
),
trailing: Icon(
Icons.arrow_forward_ios,
color: Theme.of(context).accentColor,
size: 18,
),
),
);
}
Widget renderItem(value) {
IconData icon;
String title;
Widget trailing;
Function() onTap;
bool isMultiVendor = kFluxStoreMV.contains(serverConfig['type']);
switch (value) {
case 'bookingAdmin':
if (widget.user == null ) {
return Container();
}
else if(widget.user.email == config.adminEmail || widget.user.email == config.adminEmailTwo && widget.user != null )
{
icon = FontAwesomeIcons.keyboard;
title = S.of(context).checkout;
trailing =
const Icon(Icons.arrow_forward_ios, size: 18, color: kGrey600);
onTap = () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => const BookingAdminScreen()),
);
}
else {
return Container();
}
break;
case 'addDoctorNote':
if (widget.user == null ) {
return Container();
}
else if(widget.user.isVendor && widget.user != null )
{
icon = FontAwesomeIcons.edit;
title = S.of(context).continueToShipping;
trailing =
const Icon(Icons.arrow_forward_ios, size: 18, color: kGrey600);
onTap = () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => const UserSearchNewScreen()),
);
}
else {
return Container();
}
break;
/// here is the tap to the screen where there is the error
case 'yourDoctorNotes':
if (widget.user == null || widget.user.email == config.adminEmail || widget.user.email == config.adminEmailTwo ) {
return Container();
}
else if(!widget.user.isVendor)
{
icon = FontAwesomeIcons.notesMedical;
title = S.of(context).french;
trailing =
const Icon(Icons.arrow_forward_ios, size: 18, color: kGrey600);
onTap = () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => DoctorNoteUserScreen(senderUser: widget.user,)),
);
}
else {
return Container();
}
break;
case 'chat':
here is the dart code of the screen where is the error
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:date_format/date_format.dart';
import 'package:flutter/material.dart';
import 'package:cespohm/models/bywaleed_model/user_search_new_model.dart';
import 'package:cespohm/models/bywaleed_model/user_search_new_provider.dart';
import 'package:cespohm/models/entities/user.dart';
import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;
import 'package:provider/provider.dart';
import '../../generated/l10n.dart' as word;
import '../../models/index.dart' show AppModel, Store, User, UserModel ;
final _fireStore = FirebaseFirestore.instance;
firebase_auth.User loggedInUser;
class DoctorNoteUserScreen extends StatelessWidget {
final User senderUser;
DoctorNoteUserScreen({
Key key,
this.senderUser,
}) : super(key: key);
#override
Widget build(BuildContext context) {
final userSearchProvider = Provider.of<UserSearchProvider>(context);
return Scaffold(
appBar: AppBar(
title: Text(
word.S.of(context).french,
style: TextStyle(
color: Colors.white, fontSize: 18.0, fontWeight: FontWeight.w400),
),
leading: Center(
child: GestureDetector(
child: const Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
onTap: () => Navigator.pop(context),
),
),
),
body: StreamBuilder<List<UserSearchModel>>(
stream: userSearchProvider.userstwo,
builder: (context, snapshot) {
if (!snapshot.hasData ) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).primaryColor),
),
);
} else {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(7.0),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
SizedBox(
height: 40.0,
),
Text(word.S.of(context).french,
style: TextStyle(fontSize: 18.0)),
SizedBox(
height: 15.0,
),
Divider(
thickness: 1.0,
)
],
),
),
Container(
child: ListTile(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 15.0,
),
Container(
child: Text(snapshot.data[index].doctorNote!=null?snapshot.data[index].doctorNote: 'No Notes Yet',
style: TextStyle(fontSize: 20.0)),
),
],
),
),
),
],
),
);
});
}
}),
);
}
}
here is the dart code of the service
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cespohm/models/bywaleed_model/user_search_new_model.dart';
import 'package:cespohm/models/bywaleed_model/user_search_new_provider.dart';
import 'package:cespohm/models/user_model.dart';
class UserSearchService {
final FirebaseFirestore _db = FirebaseFirestore.instance;
final userModel = UserModel();
//Get Entries
Stream<List<UserSearchModel>> getEntries(){
return _db
.collection('users')
.orderBy('firstName', descending: false)
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => UserSearchModel.fromJson(doc.data()))
.toList());
}
/// here is the firebase collection where the error exists
Stream<List<UserSearchModel>> getEntriesTwo(){
return _db
.collection('users').where('email', isEqualTo: userModel.user.email)
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => UserSearchModel.fromJson(doc.data()))
.toList());
}
}
here is the model
import 'package:cloud_firestore/cloud_firestore.dart';
class UserSearchModel {
final String date;
final String firstName;
final String lastName;
final String phone;
final String email;
final String searchKey;
final String doctorNote;
final String bYDoctor;
final String uID;
UserSearchModel(
{this.date,
this.firstName,
this.lastName,
this.phone,
this.email,
this.searchKey,
this.doctorNote,
this.bYDoctor,
this.uID});
// creating a Trip object from a firebase snapshot
UserSearchModel.fromSnapshot(DocumentSnapshot snapshot) :
date = snapshot['date'],
firstName = snapshot['firstName'].toDate(),
lastName = snapshot['lastName'].toDate(),
phone = snapshot['phone'],
email = snapshot['email'],
searchKey = snapshot['searchKey'],
doctorNote = snapshot['doctorNote'],
bYDoctor = snapshot['bYDoctor'],
uID = snapshot.id;
factory UserSearchModel.fromJson(Map<String, dynamic> json) {
return UserSearchModel(
date: json['createdAt'],
firstName: json['firstName'],
lastName: json['lastName'],
phone: json['phone'],
email: json['email'],
searchKey: json['searchKey'],
doctorNote: json['doctorNote'],
bYDoctor: json['bYDoctor'],
uID: json['uID']);
}
Map<String, dynamic> toMap() {
return {
'createdAt': date,
'firstName': firstName,
'lastName': lastName,
'phone': phone,
'email': email,
'searchKey': searchKey,
'doctorNote': doctorNote,
'bYDoctor': bYDoctor,
'uID': uID,
};
}
}
Here is the provider
import 'package:flutter/material.dart';
import 'package:cespohm/models/bywaleed_model/user_search_new_model.dart';
import 'package:cespohm/models/user_model.dart';
import 'package:cespohm/services/bywaleed/user_search_new_service.dart';
import 'package:uuid/uuid.dart';
class UserSearchProvider with ChangeNotifier {
final userSearchService = UserSearchService();
final userModel = UserModel();
DateTime _date;
String _firstName;
String _lastName;
String _phone;
String _email;
String _searchKey;
String _doctorNote;
String _bYDoctor;
String _uID;
var uuid = Uuid();
//Getters
DateTime get date => _date;
String get firstName => _firstName;
String get lastName => _lastName;
String get phone => _phone;
String get email => _email;
String get searchKey => _searchKey;
String get doctorNote => _doctorNote;
String get byDoctor => _bYDoctor;
String get uID => _uID;
Stream<List<UserSearchModel>> get users => userSearchService.getEntries();
Stream<List<UserSearchModel>> get userstwo => userSearchService.getEntriesTwo();
//Setters
set changeDate(DateTime date) {
_date = date;
notifyListeners();
}
set changeFirstName(String firstName) {
_firstName = firstName;
notifyListeners();
}
set changeLastName(String lastName) {
_lastName = lastName;
notifyListeners();
}
set changePhone(String phone) {
_phone = phone;
notifyListeners();
}
set changeEmail(String email) {
_email = email;
notifyListeners();
}
set changeSearchKey(String searchKey) {
_searchKey = searchKey;
notifyListeners();
}
set changeDoctorNote(String doctorNote) {
_doctorNote = doctorNote;
notifyListeners();
}
set changeBYDoctor(String bYDoctor) {
_bYDoctor = bYDoctor;
notifyListeners();
}
set changeuID(String uID) {
_uID = uID;
notifyListeners();
}
//Functions
loadAll(UserSearchModel userSearchModel) {
if (userSearchModel != null) {
_date = DateTime.parse(userSearchModel.date);
_firstName = userSearchModel.firstName;
_lastName = userSearchModel.lastName;
_phone = userSearchModel.phone;
_email = userSearchModel.email;
_searchKey = userSearchModel.searchKey;
_doctorNote = userSearchModel.doctorNote;
_bYDoctor = userModel.user.email;
_uID = userSearchModel.uID;
} else {
_date = DateTime.now();
_firstName = null;
_lastName = null;
_phone = null;
_email = null;
_searchKey = null;
_doctorNote = null;
_bYDoctor = null;
_uID = null;
}
}
saveEntry() {
if (_email == null) {
//Add
var newUserModel = UserSearchModel(
date: _date.toIso8601String(),
firstName: _firstName,
lastName: _lastName,
phone: _phone,
email: _email,
searchKey: _searchKey,
doctorNote: _doctorNote,
bYDoctor: _bYDoctor,
uID: _uID);
print(newUserModel.email);
userSearchService.setEntry(newUserModel);
} else {
//Edit
var updatedEntry = UserSearchModel(
date: _date.toIso8601String(),
firstName: _firstName,
lastName: _lastName,
phone: _phone,
email: _email,
searchKey: _searchKey,
doctorNote: _doctorNote,
bYDoctor: _bYDoctor,
uID: _uID);
userSearchService.setEntry(updatedEntry);
}
}
removeEntry(String entryId) {
userSearchService.removeEntry(entryId);
}
}
You need to make sure your User object is initialised. This error appears because user.email is accessed, but your User object is null. Make sure your code considers loading time for the user object if it comes from the API, and has appropriate checks for the case when user == null.

How to delete picture from the data file in flutter app

In my app I am taking picture and storing it in the device also storing the path using sqlite . Now if I delete the data using the code given below it delete from the local database(sqlite) but do not delete the picture from the file . for example I create 3 transaction and delete 2 of them but in file I still have 3 images(in file) . So how to delete them . please help .
Saving :
Future _takeImage() async {
PickedFile imageFile = await ImagePicker().getImage(
source: ImageSource.camera,
maxWidth: 600,
);
_saveImg(imageFile);
}
Future _saveImg(PickedFile imageFile) async {
if (imageFile == null) {
return;
}
setState(() {
_storedImage = File(imageFile.path);
});
final appDirectory = await sysPath.getApplicationDocumentsDirectory();
final fileName =
path.basename(_storedImage.path); //name of the photo created by camera.
final savedImage = await _storedImage
.copy('${appDirectory.path}/$fileName'); // storing image.
widget.onSelectImage(savedImage.path);
}
Deleting :
Future<void> deleteExpanse(int id) async {
try {
final MyDatabase dbManager = MyDatabase();
await dbManager.deleteTransaction(id, "Expense");
DataSample temp = _expenseItems.firstWhere((element) => id == element.id);
await _deleteImage(temp);
_expenseItems.removeWhere((element) => element.id == id);
} catch (error) {
throw error;
}
notifyListeners();
}
_deleteImage(DataSample data )async {
final directory = await getApplicationDocumentsDirectory();
final path = join(directory.path, data.image );
bool isExist = await File(path).exists();
if (isExist) {
await File(path).delete();
}
}
for detail code :
taking or choosing picture from here and passing it to a method =>
class ImageInput extends StatefulWidget {
final Function onSelectImage;
final String imageFile;
ImageInput(this.onSelectImage, this.imageFile);
#override
_ImageInputState createState() => _ImageInputState();
}
class _ImageInputState extends State<ImageInput> {
File _storedImage;
Future _choseImage() async {
try {
PickedFile imageFile = await ImagePicker().getImage(
source: ImageSource.gallery,
maxWidth: 600,
);
_saveImg(imageFile);
} catch (error) {
throw error;
}
}
Future _takeImage() async {
try {
PickedFile imageFile = await ImagePicker().getImage(
source: ImageSource.camera,
maxWidth: 600,
);
_saveImg(imageFile);
} catch (error) {
throw error;
}
}
Future _saveImg(PickedFile imageFile) async {
try {
if (imageFile == null) {
return;
}
bool a = await File(imageFile.path).exists();
setState(() {
if(a){
_storedImage = File(imageFile.path);
}
});
final appDirectory = await sysPath.getApplicationDocumentsDirectory();
final fileName = path
.basename(_storedImage.path); //name of the photo created by camera.
final savedImage = await _storedImage
.copy('${appDirectory.path}/$fileName'); // storing image.
widget.onSelectImage(savedImage.path);
} catch (error) {
throw error;
}
}
#override
void initState() {
// TODO: implement initState
_storedImage = widget.imageFile.isEmpty ? null : File(widget.imageFile);
super.initState();
}
#override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.24,
width: MediaQuery.of(context).size.width * 0.5,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(width: 1, color: Color(0xFF495464)),
),
child: _storedImage != null
? Image.file(
_storedImage,
fit: BoxFit.cover,
width: double.infinity,
)
: Text(
"No Image Chosen",
style: GoogleFonts.courgette(
fontSize: MediaQuery.of(context).size.width * 0.05),
),
alignment: Alignment.center,
),
SizedBox(width: 10),
Expanded(
child: FittedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FlatButton.icon(
icon: Icon(
Icons.camera,
color: Color(0xFF495464),
),
label: Text(
'Take Picture',
style: TextStyle(color: Color(0xFF495464), fontSize: 20),
),
onPressed: _takeImage,
),
FlatButton.icon(
icon: Icon(
Icons.photo_library,
color: Color(0xFF495464),
),
label: Text(
'Choose Picture',
style: TextStyle(color: Color(0xFF495464), fontSize: 20),
),
onPressed: _choseImage,
),
],
),
),
),
],
);
}
}
it comes here and then I pass it to the provider delete method given above(I only give the expense delete method above) =>
var _initState = true;
var trData;
String initialPrice = '';
var _newTransaction = DataSample(
id: null,
datetime: null,
title: '',
image: '',
price: 0.0,
description: '',
);
#override
void didChangeDependencies() {
if (_initState) {
trData = ModalRoute.of(context).settings.arguments as Map;
if (trData['id'] != 0) {
if (trData['type'] == "Expense") {
_newTransaction = Provider.of<ExpanseProvider>(context, listen: false)
.findId(trData['id']);
} else {
_newTransaction = Provider.of<IncomeProvider>(context, listen: false)
.findId(trData['id']);
}
_selectedDate = _newTransaction.datetime;
initialPrice = _newTransaction.price.toString();
}
}
_initState = false;
super.didChangeDependencies();
}
final _gKey = GlobalKey<FormState>();
DateTime _selectedDate = DateTime.now();
String _pickedImage = '';
void _selectImage(String pickedImage) {
_pickedImage = pickedImage;
}
void _saveInput(String page) {
final _isValid = _gKey.currentState.validate();
if (!_isValid) {
return;
}
_gKey.currentState.save();
_newTransaction = DataSample(
title: _newTransaction.title,
datetime: _selectedDate,
image: _pickedImage.isEmpty ? _newTransaction.image : _pickedImage,
id: _newTransaction.id,
price: _newTransaction.price,
description: _newTransaction.description,
);
deleteOrUpdate(page);
}
Future<void> deleteOrUpdate(String page) async {
if (_newTransaction.id == null) {
if (page == 'Expense') {
await Provider.of<ExpanseProvider>(context, listen: false)
.addExpanseTransaction(_newTransaction)
.then((value) => Navigator.of(context).pop())
.catchError((error) {
return _onError();
});
} else {
await Provider.of<IncomeProvider>(context, listen: false)
.addIncomeTransaction(_newTransaction)
.then((value) => Navigator.of(context).pop())
.catchError((error) {
return _onError();
});
}
} else {
if (page == 'Expense') {
await Provider.of<ExpanseProvider>(context, listen: false)
.updateExpense(_newTransaction)
.then((value) => Navigator.of(context).pop())
.catchError((error) {
return _onError();
});
} else {
await Provider.of<IncomeProvider>(context, listen: false)
.updateIncome(_newTransaction)
.then((value) => Navigator.of(context).pop())
.catchError((error) {
return _onError();
});
}
}
}
I once faced a similar issue using the async file deletion, I then switched to the deleteSync method. I guess in your case it should have no side effect since you already await for deletion.
Documentation: https://api.flutter.dev/flutter/dart-io/FileSystemEntity/deleteSync.html

Save Image from Image picker to firebase Storage in flutter

I am trying to upload image in firebase storage getting the image from image picker plugin by accessing camera. Image is not uploading. I also add I change the firebase rules so only authenticated users can upload the image. Git hub Repo. I used the image uploading logic defined at the auth_screen.dart Line No 48 to 59[I commented out for time being]. I also add as i add these line my other firebase fuctions which are running prefectly before. getting the errors.
auth_screen.dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
// import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/services.dart';
import '../widgets/auth/auth_form.dart';
class AuthScreen extends StatefulWidget {
#override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
final _auth = FirebaseAuth.instance;
var _isLoading = false;
void _submitAuthForm(
String email,
String password,
String userName,
File userImage,
bool isLogin,
BuildContext ctx,
) async {
dynamic authResult;
try {
setState(() {
_isLoading = true;
});
if (isLogin) {
authResult = await _auth.signInWithEmailAndPassword(
email: email,
password: password,
);
} else {
print(email);
print(userName);
print(userImage.path);
authResult = await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
// final FirebaseStorage storage = FirebaseStorage(
// app: FirebaseStorage.instance.app,
// storageBucket: 'gs://chatapp-1b780.appspot.com',
// );
// final StorageReference ref2 =
// storage.ref().child('userimage').child('${authResult.user.id}.jpg');
// final StorageUploadTask uploadTask = ref2.putFile(userImage);
// uploadTask.onComplete
// .then((value) => print(value))
// .catchError((error) => print(error));
// print(uploadTask.lastSnapshot.error.toString());
// ///...
// final ref = FirebaseStorage.instance
// .ref()
// .child('user_image')
// .child(authResult.user.id + '.jpg');
// await ref.putFile(userImage).onComplete;
///
await FirebaseFirestore.instance
.collection('users')
.doc(authResult.user.uid)
.set({
'username': userName,
'email': email,
});
}
} on PlatformException catch (error) {
var message = 'An error occured,Please check your credentials';
if (error.message != null) {
setState(() {
_isLoading = false;
});
message = error.message;
}
print(message);
} catch (error) {
setState(() {
_isLoading = false;
});
Scaffold.of(ctx).showSnackBar(
SnackBar(
content: Text(error.toString()),
backgroundColor: Theme.of(ctx).errorColor,
),
);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: AuthForm(_submitAuthForm, _isLoading),
);
}
}
image being picked using image picker from auth/auth_form.dart to user_image_picker.dart where i added the argument so the image is passed down.
auth/authform.dart
import 'package:flutter/material.dart';
import 'dart:io';
import '../pickers/user_image_picker.dart';
class AuthForm extends StatefulWidget {
final bool isLoading;
final void Function(String email, String password, String userName,
File userImage, bool isLogin, BuildContext ctx) submitFn;
AuthForm(this.submitFn, this.isLoading);
#override
_AuthFormState createState() => _AuthFormState();
}
class _AuthFormState extends State<AuthForm> {
final _formKey = GlobalKey<FormState>();
var _isLogin = true;
String _userEmail = '';
String _userName = '';
String _userPassword = '';
File _userImageFile;
void _pickedImage(File image) {
_userImageFile = image;
}
void _trysubmit() {
final isValid = _formKey.currentState.validate();
FocusScope.of(context).unfocus();
if (_userImageFile == null && !_isLogin) {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('Please Pick an Image'),
backgroundColor: Theme.of(context).errorColor,
),
);
return;
}
if (isValid) {
_formKey.currentState.save();
print(_userEmail);
print(_userPassword);
widget.submitFn(_userEmail.trim(), _userPassword.trim(), _userName.trim(),
_userImageFile, _isLogin, context);
print(_userEmail);
print(_userPassword);
}
}
#override
Widget build(BuildContext context) {
return Center(
child: Card(
margin: EdgeInsets.all(20),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
if (!_isLogin)
UserImagePicker(
imagePickFn: _pickedImage,
),
TextFormField(
key: ValueKey('emailAdress'),
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email address',
),
validator: (value) {
if (value.isEmpty || !value.contains('#')) {
return 'Please return a valid email address';
}
return null;
},
onSaved: (newValue) {
_userEmail = newValue;
},
),
if (!_isLogin)
TextFormField(
key: ValueKey('userName'),
decoration: InputDecoration(labelText: 'Username'),
validator: (value) {
if (value.isEmpty || value.length < 4) {
return 'Please Enter at least 4 characters';
}
return null;
},
onSaved: (newValue) {
_userName = newValue;
},
),
TextFormField(
key: ValueKey('password'),
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
validator: (value) {
if (value.isEmpty || value.length < 7) {
return 'Please Enter at least 7 characters';
}
return null;
},
onSaved: (newValue) {
_userPassword = newValue;
},
),
SizedBox(
height: 12,
),
if (widget.isLoading) CircularProgressIndicator(),
if (!widget.isLoading)
RaisedButton(
onPressed: _trysubmit,
child: Text((_isLogin) ? 'Login' : 'SignUp'),
),
if (!widget.isLoading)
FlatButton(
textColor: Theme.of(context).primaryColor,
child: Text(_isLogin
? 'Create new account'
: 'I already have an account'),
onPressed: () {
setState(() {
_isLogin = !_isLogin;
});
},
),
],
),
),
),
),
),
),
);
}
}
user_image_picker.dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class UserImagePicker extends StatefulWidget {
UserImagePicker({this.imagePickFn});
final void Function(File pickedImage) imagePickFn;
#override
_UserImagePickerState createState() => _UserImagePickerState();
}
class _UserImagePickerState extends State<UserImagePicker> {
File _image;
final picker = ImagePicker();
Future<void> getImage() async {
final pickedFile = await ImagePicker().getImage(source: ImageSource.camera);
setState(() {
_image = File(pickedFile.path);
});
widget.imagePickFn(_image);
}
#override
Widget build(BuildContext context) {
return Column(
children: [
CircleAvatar(
radius: 40,
backgroundColor: Colors.grey,
backgroundImage: _image != null ? FileImage(_image) : null,
),
FlatButton.icon(
onPressed: getImage,
icon: Icon(Icons.image),
label: Text('Add Image'),
textColor: Theme.of(context).primaryColor,
),
],
);
}
}
Since you asked me to show you how to upload images to Firebase Storage, I will show you the whole procedure including using the Image Picker plugin. This is how you should use Image Picker:
class PickMyImage{
static Future<File> getImage() async {
final image = await ImagePicker().getImage(
source: ImageSource.gallery,
maxHeight: 1500,
maxWidth: 1500,
);
if (image != null) {
return File(image.path);
}
return null;
}
}
This is how you can get and upload that image to firebase storage:
final File _myImage=await PickMyImage.getImage();
if(_myImage!=null){
final StorageReference firebaseStorageRef = FirebaseStorage.instance
.ref()
.child("user/${_auth.currentUser().uid}/i"); //i is the name of the image
StorageUploadTask uploadTask =
firebaseStorageRef.putFile(_myImage);
StorageTaskSnapshot storageSnapshot = await uploadTask.onComplete;
var downloadUrl = await storageSnapshot.ref.getDownloadURL();
if (uploadTask.isComplete) {
final String url = downloadUrl.toString();
print(url);
//You might want to set this as the _auth.currentUser().photourl
} else {
//error uploading
}
}
The issue i got because i am returning the ImagePicker() function of the file then gettting the image from camera then passing the file to the Fire Storage bucket.
In user_image_picker.dart
I written this
final pickedFile = await ImagePicker().getImage(source: ImageSource.camera);
Instead of i have to write this
final pickedFile = await picker.getImage(source: ImageSource.camera);

Resources