I wastrying image upload in flutter using imagepicker. While I was choose image the image cant display in one container. I was no error in error console. But the error was"Field '_image' has not been initialized. I am confused in flutter. Please he me guys
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
File? _image;
final picker = ImagePicker();
TextEditingController namecontroller = TextEditingController();
Future chooseimage() async {
var pickedImage = await picker.pickImage(source: ImageSource.gallery);
setState(() {
//_image = File(pickedImage!.path);
_image = File(pickedImage!.path);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Upload Image"),
),
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ElevatedButton(
onPressed: chooseimage,
child: Text("Select Image"),
style: ElevatedButton.styleFrom(primary: Colors.green),
),
TextField(
controller: namecontroller,
decoration: InputDecoration(label: Text("Name")),
),
SizedBox(
height: 30.0,
),
ElevatedButton(
onPressed: () {},
child: Text("Upload"),
style: ElevatedButton.styleFrom(primary: Colors.blue),
),
Container(
child: _image == null
? Text('No Image Select')
: Image.file(_image!),
),
],
),
),
),
);
}
}
///You can take a reference through this code hope this will work for you. Thanks
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:provider/provider.dart';
import 'package:traveling/Provider/EmployeeProvider/EmployeeProfileProvider.dart';
import 'package:traveling/helpers/AppColors.dart';
///To get the crop value creating a class
enum AppState {
free,
picked,
cropped,
}
class EmployeeProfile extends StatefulWidget {
final bool leadingIcon;
final number;
final cardName;
EmployeeProfile(
{Key? key, required this.leadingIcon, this.number, this.cardName})
: super(key: key);
#override
_EmployeeProfileState createState() => _EmployeeProfileState();
}
class _EmployeeProfileState extends State<EmployeeProfile>
with TickerProviderStateMixin {
EmployeeProfileProvider? _provider;
///controller widget used in Spinkit plugin to show loading process
animationControllerField(){
AnimationController animationController =AnimationController(
vsync: this, duration: const Duration(milliseconds: 900));
}
bool? visible;
double? _width;
File? _image;
var url;
late AppState state;
final picker = ImagePicker();
///pop-up to choose camera gallery while uploading image
Future<void> _showChoiceDialog(BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(
"Choose option",
style: TextStyle(color: AppColors.hotelListDarkBlue),
),
content: SingleChildScrollView(
child: ListBody(
children: [
Divider(
height: 1,
color: AppColors.baseLightBlueColor,
),
ListTile(
onTap: () {
Navigator.pop(context, _pickImage(ImageSource.gallery,context));
},
title: Text(
"Gallery",
style: TextStyle(color: AppColors.hotelListDarkBlue),
),
leading: Icon(
Icons.account_box,
color: AppColors.baseLightBlueColor,
),
),
Divider(
height: 1,
color: AppColors.baseLightBlueColor,
),
ListTile(
onTap: () {
Navigator.pop(context, _pickImage(ImageSource.camera,context));
},
title: Text(
"Camera",
style: TextStyle(color: AppColors.hotelListDarkBlue,),
),
leading: Icon(
Icons.camera,
color: AppColors.baseLightBlueColor,
),
),
],
),
),
);
});
}
///crop image selecting by the user
Future<Null> _cropImage() async {
File? croppedFile = await ImageCropper.cropImage(
sourcePath: _image!.path,
aspectRatioPresets: Platform.isAndroid
? [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
]
: [
CropAspectRatioPreset.original,
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio5x3,
CropAspectRatioPreset.ratio5x4,
CropAspectRatioPreset.ratio7x5,
CropAspectRatioPreset.ratio16x9
],
androidUiSettings: AndroidUiSettings(
toolbarTitle: 'Cropper',
toolbarColor: AppColors.baseLightBlueColor,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
iosUiSettings: IOSUiSettings(
title: 'Cropper',
));
if (croppedFile != null) {
_image = croppedFile;
setState(() {
state = AppState.cropped;
});
///to get upload image
url = await _provider!.setUserUpdatedImageInfo(_image!, );
setState(() {
///to set the image
_provider!.currentLoggedInUser!.image = url;
});
}
}
///icon change while user edit image
Widget _buildButtonIcon() {
if (state == AppState.free)
return Icon(
MdiIcons.squareEditOutline,
color: AppColors.popUpBlueColor,
size: 20,
);
else if (state == AppState.picked)
return Icon(Icons.crop,color: AppColors.popUpBlueColor,
size: 20,);
else if (state == AppState.cropped)
return Icon(
MdiIcons.squareEditOutline,
color: AppColors.popUpBlueColor,
size: 20,
);
else
return Container();
}
#override
void initState() {
// TODO: implement initState
super.initState();
print("initState called");
state = AppState.free;
_provider = EmployeeProfileProvider();
_provider!.getUserInfo();
}
///this widget is the main widget and it is used for building a UI in the app.
#override
Widget build(BuildContext context) {
_width = MediaQuery.of(context).size.width;
return ChangeNotifierProvider<EmployeeProfileProvider?>(
create: (context) => _provider!,
child: Consumer<EmployeeProfileProvider?>(
builder: (context, provider, child) {
return provider!.currentLoggedInUser==null?
Material(
color: AppColors.white,
child: Center(
child:
SpinKitCubeGrid(
color: AppColors.baseLightBlueColor,
size: 50.0,
controller:animationControllerField()
),
),
):Container(
width: _width!,
color: AppColors.white,
child: Stack(
children: [
Column(
children: [
Material(
color: AppColors.baseLightBlueColor,
elevation: 15,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.only(bottomRight: Radius.circular(30)),
),
child: Container(
height: 180,
decoration: BoxDecoration(
color: AppColors.baseLightBlueColor,
// AppColors.blue,
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(30)),
),
),
),
],
),
Positioned(
top: 80,
child:
Stack(
children: [
Container(
height: 150,
width: _width,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CachedNetworkImage(
filterQuality: FilterQuality.high,
maxHeightDiskCache: 100,
fit: BoxFit.cover,
imageUrl: provider.currentLoggedInUser!.image.toString(),
imageBuilder: (context, imageProvider) => Container(
height: 120,
width: 120,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: imageProvider, fit: BoxFit.cover),
border: Border.all(
color: AppColors.white, width: 2.0),
),
),
placeholder: (context, url) =>
const CircularProgressIndicator(),
errorWidget: (context, url, error) => Container(
height: 120,
width: 120,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
image:DecorationImage(
fit: BoxFit.cover,
image: AssetImage('assets/managerPicture.jpeg')),
border: Border.all(
color: AppColors.white, width: 2.0),
),
),
fadeOutDuration: const Duration(seconds: 1),
fadeInDuration: const Duration(seconds: 3),
),
],
),
),
Positioned(
top: 60,
right: 0,
left: 100,
bottom: 0,
child: GestureDetector(
onTap: () {
if (state == AppState.free)
_showChoiceDialog(context);
else if (state == AppState.picked)
_cropImage();
else if (state == AppState.cropped) _showChoiceDialog(context);
},
child: Container(
height: 10,
width: _width,
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Container(
height: 35,
width: 35,
decoration: BoxDecoration(
color:
AppColors.profiePicBackground,
borderRadius:
BorderRadius.circular(60),
),
child: ClipRRect(
borderRadius:
BorderRadius.circular(60.0),
child: _buildButtonIcon(),
/*Icon(
MdiIcons.squareEditOutline,
color: AppColors.popUpBlueColor,
size: 20,
),*/
),
),
],
),
),
),
)
],
)
),
Positioned(
top: 40,
child: Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.only(left: 8, right: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
widget.leadingIcon == true
? Align(
alignment: Alignment.topLeft,
child: GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(
MdiIcons.arrowLeft,
color: Colors.white,
)),
)
: Container(),
],
),
)),
],
),
);
}));
}
///ImageSource: Camera and Gallery.
Future<Null> _pickImage(ImageSource source,context) async {
final pickedImage = await ImagePicker().pickImage(source: source);
_image = pickedImage != null ? File(pickedImage.path) : null;
if (_image != null) {
setState(() {
state = AppState.picked;
});
}
}
}
class EmployeeProfileProvider extends ChangeNotifier {
late bool _isInfoEditable;
FirebaseFirestore? fireStoreInstance;
EmployeeProfileModel? _userData;
// EmployeeMyExpenseReport ? _employeeMyExpenseReport;
///to update the employee profile image
Future<String?> setUserUpdatedImageInfo(File _image, ) async {
var data= await EmployeeServices.getInstance().uploadImageToFirebase(_image, );
notifyListeners();
return data;
}
///to update Personal details of employee
EmployeeProfileModel? get getUploadedImage => _userData;
#override
void dispose() {
//print("Provider disposed called");
super.dispose();
}
//upload employee image on firebase
String ?url;
Future <String?>uploadImageToFirebase(File _image) async {
User? currentUser = FirebaseAuth.instance.currentUser;
String fileName = basename(_image.path);
firebase_storage.Reference ref = firebase_storage.FirebaseStorage.instance
.ref().child('uploads')
.child('/$fileName');
final metadata = firebase_storage.SettableMetadata(
contentType: 'image/jpeg',
customMetadata: {'picked-file-path': fileName});
firebase_storage.UploadTask uploadTask;
uploadTask = ref.putFile(io.File(_image.path), metadata);
//String ?url;
await uploadTask.whenComplete(() async {
url = await uploadTask.snapshot.ref.getDownloadURL();
});
Future.value(uploadTask)
.then((value) => {
print("Upload file path ${value.ref.fullPath}"),
FirebaseFirestore.instance.collection(FirestoreCollections.employees).doc(currentUser!.uid).update({'image': '$url'}),
})
.onError((error, stackTrace) =>
{
print("Upload file path error ${error.toString()} ")}
);
return url;
}
}
Related
The code below is my signup code, it has everything that I need but I got a problem with the default image. I made the connection with firebase but now I need to insert a default picture if the person doesn't chose a profile picture. What is the best way to tackle this?
I use de imagepicker to pick a picture from your own gallery, that is used in a async function called selectimage()
Then the async signup function is the function where the authmethods().signUpUser takes place. In this function it will then say that _image is null and that I can't use the ! operator.
import 'dart:typed_data';
import 'package:event_app/pages/Login_Page.dart';
import 'package:event_app/resources/auth_methods.dart';
import 'package:event_app/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:image_picker/image_picker.dart';
import '../utils/colors.dart';
import '../widgets/text_field_input.dart';
import '../widgets/password_field_input.dart';
import 'Verify_Email_Page.dart';
class SignupPage extends StatefulWidget {
const SignupPage({Key? key}) : super(key: key);
#override
_SignupPageState createState() => _SignupPageState();
}
class _SignupPageState extends State<SignupPage> {
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final TextEditingController _usernameController = TextEditingController();
bool _isLoading = false;
Uint8List? _image;
#override
void dispose() {
super.dispose();
_emailController.dispose();
_passwordController.dispose();
_usernameController.dispose();
}
void selectImage() async {
Uint8List im = await pickImage(ImageSource.gallery);
setState(() {
_image = im;
});
}
void signUpUser() async {
setState(() {
_isLoading = true;
});
String res = await AuthMethods().signUpUser(
email: _emailController.text,
password: _passwordController.text,
username: _usernameController.text,
file: _image!);
if (res == "Success") {
setState(() {
_isLoading = false;
});
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => const VerifyEmailPage()));
} else {
setState(() {
_isLoading = false;
});
showSnackBar(res, context);
}
}
void navigateToLogin() {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => const LoginPage()));
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 32),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Flexible(
child: Container(),
flex: 2,
),
SvgPicture.asset(
'assets/ic_instagram.svg',
color: textColor,
height: 64,
),
const SizedBox(
height: 64,
),
Stack(
children: [
_image != null
? CircleAvatar(
radius: 64,
backgroundImage: MemoryImage(_image!),
backgroundColor: Colors.grey,
)
: const CircleAvatar(
radius: 64,
backgroundImage: NetworkImage(
'https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png'),
backgroundColor: Colors.grey,
),
Positioned(
bottom: -10,
left: 80,
child: IconButton(
onPressed: selectImage,
icon: const Icon(Icons.add_a_photo)))
],
),
const SizedBox(
height: 24,
),
TextFieldInput(
hintText: 'Enter your username',
textInputType: TextInputType.text,
textEditingController: _usernameController,
),
const SizedBox(
height: 24,
),
TextFieldInput(
hintText: 'Enter your email',
textInputType: TextInputType.emailAddress,
textEditingController: _emailController,
),
const SizedBox(
height: 24,
),
PasswordFieldInput(
hintText: 'Enter your password',
textInputType: TextInputType.text,
textEditingController: _passwordController,
),
const SizedBox(
height: 24,
),
InkWell(
child: Container(
child: !_isLoading
? const Text('Sign up')
: const Center(
child: CircularProgressIndicator(
color: textColor,
),
),
width: double.infinity,
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 12),
decoration: const ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
),
color: accentColor,
),
),
onTap: signUpUser,
),
SizedBox(
height: 12,
),
Flexible(
child: Container(),
flex: 2,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: const Text("Already have an account?"),
padding: const EdgeInsets.symmetric(vertical: 8),
),
GestureDetector(
onTap: navigateToLogin,
child: Container(
child: const Text(
"Login.",
style: TextStyle(fontWeight: FontWeight.bold),
),
padding: const EdgeInsets.symmetric(vertical: 8),
),
)
],
),
],
),
)),
);
}
}
What if you change the selectImage function from async to sync function to prevent api call before _image is set.
void selectImage(){
pickImage(ImageSource.gallery).then(
(im){
setState(() {
_image = im;
});
});
}
I am currently working on Flutter application and creating a built in chat app for the application. I am not using shared preferences. I want to show all the recents chats on chat screens.
Like what's app, messenger when someone send you the message it appears in a ListTile.
Does anyone have related code or can tell me how to do it?
import 'package:bpe_application/chat/chatroom.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/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
class Conversation extends StatefulWidget {
#override
_ConversationState createState() => _ConversationState();
}
class _ConversationState extends State<Conversation> with WidgetsBindingObserver {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
#override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addObserver(this);
setStatus("Online");
}
void setStatus(String status) async{
await _firestore.collection('registration').doc(_auth.currentUser!.uid).update({
"status": status,
});
}
#override
void didChangeAppLifecycleState(AppLifecycleState state){
if (state == AppLifecycleState.resumed){
//online
setStatus("Online");
}else{
//offline
setStatus("Offline");
}
}
final FirebaseAuth _auth = FirebaseAuth.instance;
Map<String, dynamic>? userMap;
bool isLoading= false;
final TextEditingController _search = TextEditingController();
ScrollController scrollController = ScrollController();
String chatroomId(String user1, String user2){
if(user1[0].toLowerCase().codeUnits[0] > user2.toLowerCase().codeUnits[0]){
return "$user1$user2";
}else{
return "$user2$user1";
}
}
void onSearch() async {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
setState(() {
isLoading = true;
});
await _firestore.collection("registration").
where("email", isEqualTo: _search.text).
get().then((value) {
setState(() {
userMap= value.docs[0].data();
isLoading=false;
});
print(userMap);
}
);
}
void listView() async {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
setState(() {
isLoading = true;
});
await _firestore.collection("registration").
where("email", isEqualTo: _search.text).
get().then((value) {
setState(() {
userMap= value.docs[0].data();
isLoading=false;
});
print(userMap);
}
);
}
#override
Widget build(BuildContext context) {
final size= MediaQuery.of(context).size;
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: Colors.transparent, //top bar color
systemNavigationBarColor: Colors.black, //bottom bar color
systemNavigationBarIconBrightness: Brightness.dark,
));
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.transparent,
title: Padding(
padding: const EdgeInsets.fromLTRB(70, 0, 0, 0),
child: Text(
"Chat",
style: GoogleFonts.limelight(color: Colors.white),
),
),
),
body: isLoading? Center(
child: Container(
height: size.height/20,
width: size.width/20,
child: CircularProgressIndicator(),
),
)
: ClipRRect(
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(40.0),
topRight: const Radius.circular(40.0),
),
child: Container(
height: 800.0,
width: double.infinity,
color: Colors.grey.shade200,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(mainAxisSize: MainAxisSize.min, children: [
SizedBox(
height: 10,
),
Container(
height: size.height/14,
width: size.width,
alignment: Alignment.center,
child: Container(
height: size.height/14,
width: size.width/1.2,
child: TextField(
controller: _search,
decoration: InputDecoration(
hintText: "Search",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
)
),
),
),
),
SizedBox(
height: size.height/70,
),
ElevatedButton(
onPressed: onSearch,
child: Text(
"Search",style: GoogleFonts.roboto(
color: Colors.white,
),
),
),
SizedBox(
height: size.height/60,
),
userMap != null
? ListTile(
onTap: () {
String roomId = chatroomId(
_auth.currentUser!.displayName!,
userMap!['name']);
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => chatroom(
chatRoomId: roomId,
userMap: userMap!,
),
),
);
},
leading: Icon(
Icons.account_box,
color: Colors.black,
),
title: Text(
userMap!['name'],
style: GoogleFonts.roboto(
color: Colors.black,
fontSize: 17,
fontWeight: FontWeight.w500,
),
),
subtitle: Text(userMap!['email']),
trailing: Icon(
Icons.chat,
color: Colors.black,
),
)
: Container(),
],
),
),
),
),
);
}
}
Here is my home/ chat screen code
Here is my chatroom code
import 'dart:io';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
import 'package:flutter_chat_ui/flutter_chat_ui.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path/path.dart';
import 'package:uuid/uuid.dart';
class chatroom extends StatelessWidget {
final Map<String, dynamic> userMap;
final String chatRoomId;
chatroom({required this.chatRoomId, required this.userMap});
final TextEditingController _message = TextEditingController();
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
final FirebaseAuth _auth = FirebaseAuth.instance;
File? imageFile;
Future getImage() async {
ImagePicker _picker = ImagePicker();
await _picker.pickImage(source: ImageSource.gallery).then((xFile) {
if (xFile != null) {
imageFile = File(xFile.path);
uploadImage();
}
});
}
Future uploadImage() async {
String fileName = Uuid().v1();
int status = 1;
await _firestore
.collection("chatroom")
.doc(chatRoomId)
.collection('chats')
.doc(fileName)
.set({
"sendBy": _auth.currentUser!.displayName,
"message":"",
"type":"img",
"time": FieldValue.serverTimestamp(),
});
var ref =
FirebaseStorage.instance.ref().child('images').child("$fileName.jpg");
var uploadTask = await ref.putFile(imageFile!).catchError((error) async{
await _firestore
.collection("chatroom")
.doc(chatRoomId)
.collection('chats')
.doc(fileName).delete();
status = 0 ;
});
if(status==1){
String imageUrl = await uploadTask.ref.getDownloadURL();
await _firestore
.collection("chatroom")
.doc(chatRoomId)
.collection('chats')
.doc(fileName).update({
"message": imageUrl,
});
print(imageUrl);
}
}
void onSendMessage() async {
if (_message.text.isNotEmpty) {
Map<String, dynamic> messages = {
"sendBy": _auth.currentUser!.displayName,
"message": _message.text,
"type": "text",
"time": FieldValue.serverTimestamp(),
};
await _firestore
.collection('chatroom')
.doc(chatRoomId)
.collection('chats')
.add(messages);
_message.clear();
} else {
print("Enter Some Text");
}
}
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
elevation: 0.0,
backgroundColor: Colors.black,
title: Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
child: StreamBuilder<DocumentSnapshot>(
stream: _firestore
.collection("registration")
.doc(userMap['uid'])
.snapshots(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return Container(
child: Column(
children: [
Text(
userMap['name'],
style: GoogleFonts.roboto(
color: Colors.white,
fontSize: 18,
),
),
Padding(
padding: const EdgeInsets.only(right: 100),
child: Text(
snapshot.data!['status'],
style: GoogleFonts.roboto(
color: Colors.white,
fontSize: 14,
),
),
),
],
),
);
} else {
return Container();
}
},
),
),
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
height: size.height / 1.25,
width: size.width,
child: StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection('chatroom')
.doc(chatRoomId)
.collection('chats')
.orderBy("time", descending: false)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.data != null) {
return ListView.builder(
itemCount: snapshot.data?.docs.length,
itemBuilder: (context, index) {
Map<String, dynamic> map = snapshot.data!.docs[index]
.data() as Map<String, dynamic>;
return messages(size, map,context);
},
);
} else {
return Container();
}
},
),
),
],
),
),
bottomNavigationBar: Container(
color: Colors.white,
height: size.height / 10,
width: size.width,
alignment: Alignment.center,
child: Container(
height: size.height / 12,
width: size.width / 1.1,
child: Row(
children: [
Container(
height: size.height / 17,
width: size.width / 1.3,
child: TextField(
controller: _message,
decoration: InputDecoration(
suffixIcon: IconButton(
onPressed: () => getImage(),
icon: Icon(Icons.photo),
),
hintText: "Send Message",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
),
IconButton(
onPressed: onSendMessage,
icon: Icon(Icons.send),
)
],
),
),
),
);
}
Widget messages(Size size, Map<String, dynamic> map, BuildContext context) {
return map['type'] == "text"
? Container(
width: size.width,
alignment: map['sendBy'] == _auth.currentUser!.displayName
? Alignment.centerRight
: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 14),
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Colors.blue,
),
child: Text(
map['message'],
style: GoogleFonts.roboto(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
),
)
: Container(
height: size.height / 2.5,
width: size.width,
padding: EdgeInsets.symmetric(vertical: 5,horizontal: 5),
alignment: map['sendBy'] == _auth.currentUser!.displayName
? Alignment.centerRight
: Alignment.centerLeft,
child: InkWell(
onTap: () => Navigator.of(context).push(
MaterialPageRoute(builder: (_)=> ShowImage(imageURl: map['message'],
),
),
),
child: Container(
height: size.height / 2.5,
width: size.width / 2,
decoration: BoxDecoration(
border: Border.all(),
),
alignment: map['message']!="" ? null :Alignment.center,
child: map['message'] != ""
? Image.network(map['message'],fit: BoxFit.cover,)
: CircularProgressIndicator(),
),
),
);
}
}
class ShowImage extends StatelessWidget {
final imageURl;
const ShowImage({required this.imageURl, Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Scaffold(
body: Container(
height: size.height,
width: size.width,
color: Colors.black,
child: Image.network(imageURl),
),
);
}
}
I repeat I am not using shared preferences.
I need the recent chats like that in the image.
Without looking at any code, I think the idea needs planning, and then routes towards that plan's completion.
An instant chat simulation turns out to be a stream of incoming data, and a list of recents chats is also a stream of incoming data.
The answer must be to code an instant message simulation, and to then code a stream that counts conversations.
That amounts to creating a stream of streams, where a list of conversations should be developed.
To have the above in mind before the coding begins is a good idea so that you know that after producing a single chat screen, that there's still more to go.
The next question will be, how to delete conversations from the list, like, is there a widget that helps slide them away like in Whatsapp?
The image should be uploaded only to that column which is clicked not in all.
I write a code where I have columns in Gridviw and each column has the property to upload the image. The image will be uploaded on that column which is clicked but in my code when I click any column to upload an image it uploads in all columns. so I want to upload an image on a particular column that I click.
also when I upload an image and add a new column it adds a new box with an image, not blank box.
so please help me to do this.
Here is my code:-
import 'package:flutter/material.dart';
import 'package:/utils/widget_functions.dart';
import 'package:******/custom/BorderIcon.dart';
import 'package:******/screens/Relation.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
import 'dart:io';
class Photos extends StatefulWidget {
var usrid;
Photos({Key? key, #required this.usrid}) : super(key: key);
#override
_Photos createState() => _Photos();
}
class _Photos extends State<Photos>{
PickedFile? _imageFile;
final String uploadUrl = 'https://api.imgur.com/3/upload';
final ImagePicker _picker = ImagePicker();
Future<String?> uploadImage(filepath, url) async {
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(await http.MultipartFile.fromPath('image', filepath));
var res = await request.send();
return res.reasonPhrase;
}
Future<void> retriveLostData() async {
final LostData response = await _picker.getLostData();
if (response.isEmpty) {
return;
}
if (response.file != null) {
setState(() {
_imageFile = response.file;
});
} else {
print('Retrieve error ${response.exception?.code}');
}
}
int counter = 0;
//List<Widget> _list = List<Widget>();
List<Widget> _list = <Widget> [];
List<PickedFile?> _images = [];
#override
void initState() {
for (int i = 0; i < 2; i++) {
Widget child = _newItem(i);
_list.add(child);
};
}
void on_Clicked() {
Widget child = _newItem(counter);
setState(
() => _list.add(child),
);
}
Widget _previewImage(int i) {
final _imageFile = this._imageFile;
if (_imageFile != null) {
return
SizedBox(
//width: 300,
height: 100,
child: Center(child:
ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.file(
File(
_imageFile.path,
),
height: 80,
)
),
),
);
} else {
return InkWell(
onTap: () => _pickImage(i),
child: SizedBox(
//width: 300,
height: 100,
child: Center(child:
Icon(
Icons.image,
color: Color(0xffcccccc),
size: 60,
),
),
),
);
}
}
Widget _newItem(int i) {
Key key = new Key('item_${i}');
Column child = Column(
key: key,
children: [
Stack(
children: [
Card(
elevation: 0,
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xffa1a1a1),
),
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: _previewImage(i),
),
Positioned(
top: 9,
right: 9,
child: InkWell(
onTap: () => _removeItem(i),
child: SvgPicture.asset(
width: 20,
'assets/images/close.svg',
height: 20,
),
),
)
]
),
]
);
counter++;
return child;
}
void _removeItem(int i) {
print("====remove $i");
print('===Removing $i');
setState(() => _list.removeAt(i));
}
void _pickImage( int i ) async {
try {
final pickedFile = await _picker.getImage(source: ImageSource.gallery);
setState(() {
_imageFile = pickedFile;
_images.add(pickedFile);
});
} catch (e) {
//print("Image picker error ${e!}");
print("Image picker error");
}
}
#override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
final ThemeData themeData = Theme.of(context);
final double padding = 25;
final sidePadding = EdgeInsets.symmetric(horizontal: padding);
var regID = widget.usrid;
return Theme(
data: ThemeData().copyWith(
dividerColor: Colors.transparent,
backgroundColor: Colors.transparent
),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
leading: Builder(
builder: (BuildContext context) {
return Padding(padding: EdgeInsets.fromLTRB(15, 0, 0, 0),
child: IconButton(
icon: const Icon(
Icons.arrow_back_ios_outlined,
color: Colors.black,
),
onPressed: () { Navigator.pop(context); },
),
);
},
),
),
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
//colors: const [Color.fromRGBO(132,105,211,1), Color.fromRGBO(93,181,233,1), Color.fromRGBO(86,129,233,1)],
colors: [Colors.white, Colors.white]
),
),
width: size.width,
height: size.height,
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
addVerticalSpace(10),
Padding(
padding: sidePadding,
child: const Text(
'Add Your Photos',
style: TextStyle(
color: Colors.black,
fontSize: 20,
),),
),
addVerticalSpace(30),
Expanded(
child: Padding(
padding: sidePadding,
child: Column(
children: [
Expanded(
child: GridView(
//padding: const EdgeInsets.all(8.0),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10.0,
mainAxisSpacing: 15,
//childAspectRatio: 2/1,
),
// children: List.generate(_list.length, (index) {
// //generating tiles with people from list
// return _newItem(index);
// },
// ),
children: List.generate(_list.length + 1,
(index) => index == _list.length ?
InkWell(
onTap: () => on_Clicked(),
child: Column(
children: [
Stack(
children: const [
Card(
elevation: 0,
color: Color(0xff8f9df2),
shape: RoundedRectangleBorder(
side: BorderSide(
color: Color(0xff8f9df2),
),
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: SizedBox(
//width: 300,
height: 100,
child: Center(child:
Icon(
Icons.add,
color: Colors.white,
size: 80.0,
),
),
),
)
]
),
]
),
) :
_newItem(index)),
)
)
],
),
)
),
],
),
],
)
),
),
persistentFooterButtons:[
Padding(
padding: EdgeInsets.fromLTRB(18, 0, 18, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:[
ElevatedButton.icon( // <-- ElevatedButton
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.arrow_back_ios_outlined,
size: 15.0,
color:Colors.white,
),
label: const Text(
'Back',
style: TextStyle(
fontSize: 20,
),
),
style: ElevatedButton.styleFrom(
primary: Color(0xffFDA766),
minimumSize: const Size(100, 49),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0),)
),
),
Directionality(
textDirection: TextDirection.rtl,
child: ElevatedButton.icon( // <-- ElevatedButton
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Relation(usrid:regID)),
);
},
icon: const Icon(
Icons.arrow_back_ios_outlined,
size: 15.0,
color:Colors.white,
),
label: const Text(
'Next',
style: TextStyle(
fontSize: 20,
),
),
style: ElevatedButton.styleFrom(
primary: Color(0xffFDA766),
minimumSize: const Size(100, 49),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0),)
),
),
),
]
),
),
]
),
);
}
}
And here is my output:- this is the output image before image upload
After image upload:- and this image after upload where it uploads all two columns
Please help me with how I solve this.
photo of errorList item
class UserImagePicker extends StatefulWidget {
#override
_UserImagePickerState createState() => _UserImagePickerState();
}
class _UserImagePickerState extends State<UserImagePicker> {
final picker = ImagePicker();
File _imageFile;
String _currentImageUrl;
// Future pickImage() async {
// final pickedFile = await picker.getImage(source: ImageSource.gallery);
// setState(() {
// _imageFile = File(pickedFile.path);
// });
// }
Future uploadImage(BuildContext context) async {
String fileName = basename(_imageFile.path);
StorageReference storageReference =
FirebaseStorage.instance.ref().child('images/$fileName');
StorageUploadTask uploadTask = storageReference.putFile(_imageFile);
StorageTaskSnapshot taskSnapshot = await uploadTask.onComplete;
taskSnapshot.ref.getDownloadURL().then((val) {
print('Dome:$val');
setState(() {
_currentImageUrl = val;
});
});
}
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
return Scaffold(
backgroundColor: customColor,
body: StreamBuilder<Users>(
stream: DatabaseServices(userId: user.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
Users userData = snapshot.data;
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Stack(
children: [
Container(
height: 150,
width: 150,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
spreadRadius: 2,
blurRadius: 10,
color: Colors.black.withOpacity(0.1),
offset: Offset(0, 10),
),
],
border: Border.all(
color: Colors.white,
width: 3,
),
),
child: CircleAvatar(
radius: 55,
backgroundColor: Colors.white,
child: ClipOval(
child: SizedBox(
height: 150,
width: 150,
child: (_imageFile != null)
? FileImage(
_imageFile,
)
: Image(
image: NetworkImage(
UserData.userImageUrl,
),
fit: BoxFit.cover,
),
),
),
),
),
Positioned(
bottom: 0,
right: 0,
child: GestureDetector(
onTap: () {
_showPickOptionsDialog(context);
},
child: Container(
height: 35,
width: 35,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: customColor,
border: Border.all(
color: Colors.white,
width: 2,
),
),
child: Icon(
Icons.edit,
color: Colors.white,
),
),
),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
color: Colors.white,
child: Text(
getTranslated(context, 'save'),
style: AppTheme.heading.copyWith(
color: customColor,
),
),
onPressed: () {
DatabaseServices(userId: user.uid).updateUserData(
userData.phoneNumber,
userData.name,
userData.email,
_currentImageUrl ?? userData.userImageUrl,
);
DBHelper.saveUserSingIn(true);
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (_) => Home(),
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
side: BorderSide(
width: 1,
color: Colors.white,
),
),
child: Text(
getTranslated(context, 'skip'),
style: AppTheme.heading.copyWith(
color: Colors.white,
),
),
onPressed: () {
DBHelper.saveUserSingIn(true);
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (_) => Home(),
),
);
},
),
),
],
),
],
),
);
} else {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
}
},
),
);
}
_loadPicker(ImageSource source, BuildContext context) async {
// ignore: deprecated_member_use
File picked = await ImagePicker.pickImage(source: source);
if (picked != null) {
_cropImage(picked, context);
}
Navigator.of(context).pop();
}
_cropImage(File picked, BuildContext context) async {
File cropped = await ImageCropper.cropImage(
androidUiSettings: AndroidUiSettings(
statusBarColor: Colors.red,
toolbarColor: Colors.red,
toolbarTitle: "Crop Image",
toolbarWidgetColor: Colors.white,
),
sourcePath: picked.path,
aspectRatioPresets: [
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio16x9,
CropAspectRatioPreset.ratio4x3,
],
maxWidth: 800,
);
if (cropped != null) {
setState(() {
_imageFile = cropped;
uploadImage(context);
});
}
}
void _showPickOptionsDialog(BuildContext context) {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text("Pick from Gallery"),
onTap: () {
_loadPicker(ImageSource.gallery, context);
},
),
ListTile(
title: Text("Take a pictuer"),
onTap: () {
_loadPicker(ImageSource.camera, context);
},
)
],[enter image description here][1]
),
),
);
}
}
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.vanillia">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"/>
error:
in photo
PlatformException (PlatformException(error, Unable to find explicit activity class {com.example.vanillia/c.e.a.j}; have you declared this activity in your AndroidManifest.xml?, null, android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.vanillia/c.e.a.j}; have you declared this activity in your AndroidManifest.xml?
This question already has answers here:
What is a NoSuchMethod error and how do I fix it?
(2 answers)
Closed 2 years ago.
In my flutter project, i used CachedNetworkImageProvider, in which i passed photo url, but it is showing me an error, that it is called on null. Can anyone help me please? Check out line 158. If you think, there is nothing wrong in this part, and some other widget is causing the error, (that are made by me), then please tell me, i will provide you that. Please help me. I am new to this thing.
Here's the exception -
The getter 'photoUrl' was called on null.
Receiver: null
Tried calling: photoUrl
The relevant error-causing widget was:
Upload file:///C:/Users/Hp/AndroidStudioProjects/social_app/lib/pages/home.dart:117:11
Here's the code -
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_picker/image_picker.dart';
import 'package:social_app/models/users.dart';
class Upload extends StatefulWidget {
final User currentUser;
Upload({this.currentUser});
#override
_UploadState createState() => _UploadState();
}
class _UploadState extends State<Upload> {
File file;
handleTakePhoto() async {
Navigator.pop(context);
File file = await ImagePicker.pickImage(source: ImageSource.camera, maxWidth: 960, maxHeight: 675);
// ImagePicker imagePicker;
// PickedFile pickedFile = await imagePicker.getImage(source: ImageSource.camera, maxHeight: 675, maxWidth: 960);
// File file = File(pickedFile.path);
setState(() {
this.file = file;
});
}
handleChooseFromGallery() async{
Navigator.pop(context);
File file = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
this.file = file;
});
// ImagePicker imagePicker;
// PickedFile pickedFile = await imagePicker.getImage(source: ImageSource.gallery);
// File file = File(pickedFile.path);
// setState(() {
// this.file = file;
// });
}
selectImage(parentContext) {
return showDialog(
context: parentContext,
builder: (context) {
return SimpleDialog(
title: Text('Create Post'),
children: <Widget>[
SimpleDialogOption(
child: Text('Click Photo'),
onPressed: handleTakePhoto,
),
SimpleDialogOption(
child: Text('Import from Gallery'),
onPressed: handleChooseFromGallery,
),
SimpleDialogOption(
child: Text('Cancel'),
onPressed: () => Navigator.pop(context),
),
],
);
}
);
}
Container buildSplashScreen() {
return Container(
color: Colors.black54,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SvgPicture.asset('assets/images/upload.svg', height: 300.0,),
Padding(
padding: EdgeInsets.only(top: 40.0),
child: RaisedButton(
padding: EdgeInsets.all(10.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
child: Text(
'Upload Image',
style: TextStyle(
color: Colors.white,
fontSize: 30.0,
),
),
color: Colors.blueGrey[600],
onPressed: () => selectImage(context),
),
),
],
),
);
}
clearImage() {
setState(() {
file =null;
});
}
Scaffold buildUploadForm() {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white70,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black,),
onPressed: clearImage,
),
title: Center(
child: Text(
'Caption Post',
style: TextStyle(
color: Colors.black,
),
),
),
actions: [
FlatButton(
onPressed: () => print('Pressed'),
child: Text(
'Post',
style: TextStyle(
color: Colors.blueAccent,
fontWeight: FontWeight.bold,
fontSize: 20.0,
),
),
),
],
),
body: ListView(
children: <Widget>[
Container(
height: 220.0,
width: MediaQuery.of(context).size.width * 0.8,
child: Center(
child: AspectRatio(
aspectRatio: 16/9,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: FileImage(file),
),
),
),
),
),
),
Padding(
padding: EdgeInsets.only(top: 10.0),
),
ListTile(
leading: CircleAvatar(
backgroundImage: CachedNetworkImageProvider(widget.currentUser.photoUrl),
),
title: Container(
width: 250.0,
child: TextField(
decoration: InputDecoration(
hintText: "Write a caption..",
border: InputBorder.none,
),
),
),
),
Divider(
),
ListTile(
leading: Icon(
Icons.pin_drop,
color: Colors.blue,
size: 36.0,
),
title: Container(
width: 250.0,
child: TextField(
decoration: InputDecoration(
hintText: 'Search a location...',
border: InputBorder.none,
),
),
),
),
Container(
width: 200.0,
height: 100.0,
alignment: Alignment.center,
child: RaisedButton.icon(
label: Text(
'Use current location...',
style: TextStyle(
color: Colors.white,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
color: Colors.blue,
onPressed: () => print('Get user location'),
icon: Icon(
Icons.my_location,
color: Colors.white,
),
),
),
],
),
);
}
#override
Widget build(BuildContext context) {
return file == null ? SafeArea(
child: Scaffold(
backgroundColor: Colors.black45,
body: buildSplashScreen(),
),
) : buildUploadForm();
}
}
home page -
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:social_app/pages/activity_feed.dart';
import 'package:social_app/pages/create_account.dart';
import 'package:social_app/pages/profile.dart';
import 'package:social_app/pages/search.dart';
import 'package:social_app/pages/timeline.dart';
import 'package:social_app/pages/upload.dart';
import 'package:social_app/widgets/header.dart';
import 'package:social_app/models/users.dart';
final GoogleSignIn googleSignIn = GoogleSignIn();
final usersRef = FirebaseFirestore.instance.collection('users');
final DateTime timeStamp = DateTime.now();
User currentUser;
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
bool isAuth = false;
PageController pageController;
int pageIndex=0;
#override
void initState(){
super.initState();
pageController = PageController(initialPage: 0);
googleSignIn.onCurrentUserChanged.listen((account) {
handleSignIn(account);
},
onError: (error) {
print("Error in signing in : $error");
});
googleSignIn.signInSilently(suppressErrors: false).then((account){
handleSignIn(account);
}).catchError((error){
print("Error in signing in : $error");
});
}
handleSignIn(GoogleSignInAccount account) {
if (account != null) {
createUserInFirestore();
setState(() {
isAuth = true;
});
}
else {
setState(() {
isAuth = false;
});
}
}
createUserInFirestore() async{
final GoogleSignInAccount user = googleSignIn.currentUser;
DocumentSnapshot doc = await usersRef.doc(user.id).get();
if(!doc.exists) {
final username = await Navigator.push(context, MaterialPageRoute(builder: (context) => CreateAccount()));
usersRef.doc(user.id).set({
"id" : user.id,
"username" : username,
"photoUrl" : user.photoUrl,
"email" : user.email,
"displayName" : user.displayName,
"bio" : "",
"timeStamp" : timeStamp,
});
}
}
#override
void dispose() {
pageController.dispose();
super.dispose();
}
login() {
googleSignIn.signIn();
}
logout() {
googleSignIn.signOut();
}
onPageChanged(int pageIndex) {
setState(() {
this.pageIndex = pageIndex;
});
}
onTap(int pageIndex) {
pageController.animateToPage(
pageIndex,
duration: Duration(milliseconds: 250),
curve: Curves.easeInOut,
);
}
Scaffold buildAuthScreen(){
return Scaffold(
body: PageView(
children: <Widget>[
//Timeline(),
RaisedButton(
onPressed: logout,
child: Text('logout'),
),
Search(),
Upload(currentUser: currentUser),
ActivityFeed(),
Profile(),
],
controller: pageController,
onPageChanged: onPageChanged,
physics: NeverScrollableScrollPhysics(),
),
bottomNavigationBar: CupertinoTabBar(
backgroundColor: Colors.black,
currentIndex: pageIndex,
onTap: onTap,
activeColor: Colors.white,
items: [
BottomNavigationBarItem(icon: Icon(Icons.home_filled)),
BottomNavigationBarItem(icon: Icon(Icons.search)),
BottomNavigationBarItem(icon: Icon(Icons.add_box_outlined)),
BottomNavigationBarItem(icon: Icon(Icons.favorite_border)),
BottomNavigationBarItem(icon: Icon(Icons.account_circle)),
],
),
);
// return RaisedButton(
// onPressed: logout,
// child: Text('logout'),
// );
}
Scaffold buildUnauthScreen() {
return Scaffold(
appBar: header(context, titleText: 'Instagram'),
backgroundColor: Colors.black,
body: SafeArea(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [
Theme.of(context).primaryColor,
Colors.teal.withOpacity(1.0),
Colors.orange,
]
),
),
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'Technua',
style: GoogleFonts.gochiHand(
fontSize: 70.0,
color: Colors.white,
),
),
GestureDetector(
onTap: login,
child: Container(
height: 60.0,
width: 260.0,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/google_signin_button.png'),
fit: BoxFit.cover,
)
),
),
),
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
return isAuth ? buildAuthScreen() : buildUnauthScreen();
}
}
You have created an optional named parameter currentUser in your StatefulWidget Upload. I think the user that you have passed in the Upload widget is null.
You have to check where are you calling the Upload widget from & then check whether the user is null or not.
However, if the currentUser is null, you can prevent the error by using null aware operator as follows:
leading: CircleAvatar(
backgroundImage: CachedNetworkImageProvider(
widget.currentUser?.photoUrl, // <-----
),
),
Your current user is null. You have to set a user in here:
final User currentUser;