before rediense
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:user_repository/user_repository.dart';
|
import 'package:user_repository/user_repository.dart';
|
||||||
|
|||||||
@@ -11,27 +11,33 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
|||||||
ProfileBloc({required UserRepository userRepository})
|
ProfileBloc({required UserRepository userRepository})
|
||||||
: _userRepository = userRepository,
|
: _userRepository = userRepository,
|
||||||
super(UpdateUserInfoInitial()) {
|
super(UpdateUserInfoInitial()) {
|
||||||
on<UploadPicture>(_onUploadPicture);
|
// on<UploadPicture>(_onUploadPicture);
|
||||||
on<UpdateUserInfo>(_onUpdateUserInfo);
|
on<UpdateUserInfo>(_onUpdateUserInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onUploadPicture(UploadPicture event, Emitter<ProfileState> emit) async {
|
// void _onUploadPicture(UploadPicture event, Emitter<ProfileState> emit) async {
|
||||||
emit(UploadPictureLoading());
|
// emit(UploadPictureLoading());
|
||||||
try {
|
// try {
|
||||||
String userImage =
|
// String userImage =
|
||||||
await _userRepository.uploadPicture(event.file, event.userId);
|
// await _userRepository.uploadPicture(event.file, event.userId);
|
||||||
emit(UploadPictureSuccess(userImage));
|
// emit(UploadPictureSuccess(userImage));
|
||||||
} catch (e) {
|
// } catch (e) {
|
||||||
emit(UploadPictureFailure());
|
// emit(UploadPictureFailure());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
void _onUpdateUserInfo(
|
void _onUpdateUserInfo(
|
||||||
UpdateUserInfo event, Emitter<ProfileState> emit) async {
|
UpdateUserInfo event, Emitter<ProfileState> emit) async {
|
||||||
emit(UpdateUserInfoLoading());
|
emit(UpdateUserInfoLoading());
|
||||||
try {
|
try {
|
||||||
await _userRepository.updateUserInfo(event.userId, {
|
await _userRepository.updateUserInfo(event.userId, event.picture, {
|
||||||
'name': event.name,
|
'name': event.name,
|
||||||
|
// 'picture': event.picture,
|
||||||
|
'nickname': event.nickname,
|
||||||
|
'email': event.email,
|
||||||
|
'phone': event.phone,
|
||||||
|
'birthDate': event.birthDate,
|
||||||
|
'gender': event.gender
|
||||||
});
|
});
|
||||||
emit(const UpdateUserInfoSuccess());
|
emit(const UpdateUserInfoSuccess());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ abstract class ProfileEvent extends Equatable {
|
|||||||
const ProfileEvent();
|
const ProfileEvent();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object?> get props => [];
|
||||||
}
|
}
|
||||||
|
|
||||||
class UploadPicture extends ProfileEvent {
|
class UploadPicture extends ProfileEvent {
|
||||||
@@ -14,15 +14,31 @@ class UploadPicture extends ProfileEvent {
|
|||||||
const UploadPicture(this.file, this.userId);
|
const UploadPicture(this.file, this.userId);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [file, userId];
|
List<Object?> get props => [file, userId];
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpdateUserInfo extends ProfileEvent {
|
class UpdateUserInfo extends ProfileEvent {
|
||||||
final String userId;
|
final String userId;
|
||||||
final String name;
|
final String picture;
|
||||||
|
final String? name;
|
||||||
|
final String? nickname;
|
||||||
|
final String? email;
|
||||||
|
final String? phone;
|
||||||
|
final String? birthDate;
|
||||||
|
final String? gender;
|
||||||
|
|
||||||
const UpdateUserInfo(this.userId, this.name);
|
const UpdateUserInfo({
|
||||||
|
required this.userId,
|
||||||
|
required this.picture,
|
||||||
|
this.name,
|
||||||
|
this.nickname,
|
||||||
|
this.email,
|
||||||
|
this.phone,
|
||||||
|
this.birthDate,
|
||||||
|
this.gender,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [userId, name];
|
List<Object?> get props =>
|
||||||
|
[userId, name, nickname, email, phone, picture, birthDate, gender];
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-7
@@ -5,11 +5,10 @@ class BirthDatePicker extends StatefulWidget {
|
|||||||
final TextEditingController controller;
|
final TextEditingController controller;
|
||||||
|
|
||||||
const BirthDatePicker(
|
const BirthDatePicker(
|
||||||
{Key? key, required this.onDateSelected, required this.controller})
|
{super.key, required this.onDateSelected, required this.controller});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_BirthDatePickerState createState() => _BirthDatePickerState();
|
State<BirthDatePicker> createState() => _BirthDatePickerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BirthDatePickerState extends State<BirthDatePicker> {
|
class _BirthDatePickerState extends State<BirthDatePicker> {
|
||||||
@@ -39,10 +38,20 @@ class _BirthDatePickerState extends State<BirthDatePicker> {
|
|||||||
_selectDate(context);
|
_selectDate(context);
|
||||||
},
|
},
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
prefixIcon: Icon(Icons.calendar_month),
|
labelText: 'Fecha de nacimiento',
|
||||||
suffixIcon: Icon(Icons.arrow_drop_down),
|
prefixIcon: const Icon(Icons.calendar_month_rounded),
|
||||||
hintText: 'Fecha de nacimiento',
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
errorBorder: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(color: Colors.red),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
|
borderSide: const BorderSide(color: Colors.red, width: 2.0),
|
||||||
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
controller: widget.controller,
|
controller: widget.controller,
|
||||||
);
|
);
|
||||||
+15
-7
@@ -3,10 +3,10 @@ import 'package:flutter/material.dart';
|
|||||||
class GenderDropdown extends StatefulWidget {
|
class GenderDropdown extends StatefulWidget {
|
||||||
final Function(String) onChanged;
|
final Function(String) onChanged;
|
||||||
|
|
||||||
const GenderDropdown({Key? key, required this.onChanged}) : super(key: key);
|
const GenderDropdown({super.key, required this.onChanged});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_GenderDropdownState createState() => _GenderDropdownState();
|
State<GenderDropdown> createState() => _GenderDropdownState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GenderDropdownState extends State<GenderDropdown> {
|
class _GenderDropdownState extends State<GenderDropdown> {
|
||||||
@@ -15,16 +15,24 @@ class _GenderDropdownState extends State<GenderDropdown> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return InputDecorator(
|
return InputDecorator(
|
||||||
decoration: const InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: UnderlineInputBorder(),
|
border: OutlineInputBorder(
|
||||||
prefixIcon: Icon(Icons.people_outline),
|
borderRadius: BorderRadius.circular(10.0),
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 8.0),
|
),
|
||||||
|
prefixIcon: const Icon(Icons.groups),
|
||||||
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 12.0,
|
||||||
|
vertical: 7.0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: DropdownButtonHideUnderline(
|
child: DropdownButtonHideUnderline(
|
||||||
child: DropdownButton<String>(
|
child: DropdownButton<String>(
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
value: selectedGender,
|
value: selectedGender,
|
||||||
hint: const Text('Selecciona tu género'),
|
hint: const Text(
|
||||||
|
'Selecciona tu género',
|
||||||
|
style: TextStyle(fontSize: 16.0),
|
||||||
|
),
|
||||||
onChanged: (String? newValue) {
|
onChanged: (String? newValue) {
|
||||||
setState(() {
|
setState(() {
|
||||||
selectedGender = newValue;
|
selectedGender = newValue;
|
||||||
@@ -26,10 +26,13 @@ class GeneralDrawerHeader extends StatelessWidget {
|
|||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
context.read<MyUserBloc>().state.user!.email ?? '',
|
context.read<MyUserBloc>().state.user!.email ??
|
||||||
|
context.read<MyUserBloc>().state.user!.phone ??
|
||||||
|
'',
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
),
|
),
|
||||||
leading: context.read<MyUserBloc>().state.user!.picture == ""
|
leading: context.read<MyUserBloc>().state.user!.picture == "" ||
|
||||||
|
context.read<MyUserBloc>().state.user!.picture == null
|
||||||
? Container(
|
? Container(
|
||||||
width: 80,
|
width: 80,
|
||||||
height: 80,
|
height: 80,
|
||||||
@@ -51,7 +54,7 @@ class GeneralDrawerHeader extends StatelessWidget {
|
|||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: NetworkImage(
|
image: NetworkImage(
|
||||||
context.read<MyUserBloc>().state.user!.picture!,
|
context.read<MyUserBloc>().state.user?.picture ?? '',
|
||||||
),
|
),
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class AboutScreen extends StatelessWidget {
|
||||||
|
const AboutScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Placeholder();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart';
|
import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart';
|
||||||
import 'package:prosappco/blocs/profile_bloc/profile_bloc.dart';
|
import 'package:prosappco/blocs/profile_bloc/profile_bloc.dart';
|
||||||
|
import 'package:prosappco/components/birth_date_picker.dart';
|
||||||
|
import 'package:prosappco/components/gender_dropdown.dart';
|
||||||
|
import 'package:prosappco/components/general_primary_button.dart';
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
|
|
||||||
class ProfileScreen extends StatefulWidget {
|
class ProfileScreen extends StatefulWidget {
|
||||||
@@ -15,10 +21,19 @@ class ProfileScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _ProfileScreenState extends State<ProfileScreen> {
|
class _ProfileScreenState extends State<ProfileScreen> {
|
||||||
final TextEditingController _nameController = TextEditingController();
|
final TextEditingController _nameController = TextEditingController();
|
||||||
|
final TextEditingController _emailController = TextEditingController();
|
||||||
|
final TextEditingController _phoneController = TextEditingController();
|
||||||
|
final TextEditingController _birthDateController = TextEditingController();
|
||||||
|
final TextEditingController _genderController = TextEditingController();
|
||||||
|
XFile? _imageFile;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_nameController.dispose();
|
_nameController.dispose();
|
||||||
|
_emailController.dispose();
|
||||||
|
_phoneController.dispose();
|
||||||
|
_birthDateController.dispose();
|
||||||
|
_genderController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,8 +55,11 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
body: BlocBuilder<MyUserBloc, MyUserState>(builder: (context, state) {
|
body: BlocBuilder<MyUserBloc, MyUserState>(builder: (context, state) {
|
||||||
if (state.status == MyUserStatus.success) {
|
if (state.status == MyUserStatus.success) {
|
||||||
_nameController.text = state.user!.name ?? '';
|
_nameController.text = state.user!.name ?? '';
|
||||||
|
_emailController.text = state.user!.email ?? '';
|
||||||
|
_phoneController.text = state.user!.phone ?? '';
|
||||||
|
|
||||||
return Padding(
|
return SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(20.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
@@ -57,13 +75,30 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
context.read<ProfileBloc>().add(
|
// context
|
||||||
UploadPicture(image.path, state.user!.id),
|
// .read<ProfileBloc>()
|
||||||
);
|
// .add(UploadPicture(image.path, state.user!.id));
|
||||||
|
setState(() {
|
||||||
|
_imageFile = image;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: state.user!.picture == ""
|
child: state.user!.picture == "" ||
|
||||||
|
state.user!.picture == null
|
||||||
|
? _imageFile != null
|
||||||
? Container(
|
? Container(
|
||||||
|
width: 150,
|
||||||
|
height: 150,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey,
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
image: DecorationImage(
|
||||||
|
image: FileImage(File(_imageFile!.path)),
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: Container(
|
||||||
width: 120,
|
width: 120,
|
||||||
height: 120,
|
height: 120,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -83,13 +118,12 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
shape: BoxShape.circle,
|
shape: BoxShape.circle,
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
image: NetworkImage(
|
image: NetworkImage(context
|
||||||
context
|
|
||||||
.read<MyUserBloc>()
|
.read<MyUserBloc>()
|
||||||
.state
|
.state
|
||||||
.user!
|
.user
|
||||||
.picture!,
|
?.picture ??
|
||||||
),
|
''),
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -104,7 +138,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
hintText: 'Nombre (obligatorio)',
|
hintText: 'Nombre (obligatorio)',
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(
|
||||||
Radius.circular(25.0),
|
Radius.circular(10.0),
|
||||||
)),
|
)),
|
||||||
errorBorder: OutlineInputBorder(
|
errorBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: Colors.red),
|
borderSide: BorderSide(color: Colors.red),
|
||||||
@@ -122,13 +156,14 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 20.0),
|
const SizedBox(height: 20.0),
|
||||||
TextFormField(
|
TextFormField(
|
||||||
|
controller: _emailController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: 'Nombre',
|
labelText: 'Email',
|
||||||
prefixIcon: Icon(Icons.person),
|
prefixIcon: Icon(Icons.email_rounded),
|
||||||
hintText: 'Nombre (obligatorio)',
|
hintText: 'Email',
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
borderRadius: BorderRadius.all(
|
borderRadius: BorderRadius.all(
|
||||||
Radius.circular(25.0),
|
Radius.circular(10.0),
|
||||||
)),
|
)),
|
||||||
errorBorder: OutlineInputBorder(
|
errorBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: Colors.red),
|
borderSide: BorderSide(color: Colors.red),
|
||||||
@@ -137,22 +172,67 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
borderSide: BorderSide(color: Colors.red, width: 2.0),
|
borderSide: BorderSide(color: Colors.red, width: 2.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
validator: (value) {
|
|
||||||
if (value == null || value.isEmpty) {
|
|
||||||
return 'Por favor, ingrese su nombre';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 20.0),
|
||||||
|
TextFormField(
|
||||||
|
controller: _phoneController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Número de Teléfono',
|
||||||
|
prefixIcon: Icon(Icons.phone_android_rounded),
|
||||||
|
hintText: '+57',
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(
|
||||||
|
Radius.circular(10.0),
|
||||||
|
)),
|
||||||
|
errorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.red),
|
||||||
|
),
|
||||||
|
focusedErrorBorder: OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Colors.red, width: 2.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20.0),
|
||||||
|
BirthDatePicker(
|
||||||
|
onDateSelected: (birthDay) {
|
||||||
|
_birthDateController.text =
|
||||||
|
DateFormat('dd/MM/yyyy').format(birthDay);
|
||||||
|
},
|
||||||
|
controller: _birthDateController,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20.0),
|
||||||
|
GenderDropdown(onChanged: (selectedGender) {
|
||||||
|
_genderController.text = selectedGender;
|
||||||
|
}),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
context.read<ProfileBloc>().add(
|
context.read<ProfileBloc>().add(
|
||||||
UpdateUserInfo(state.user!.id, _nameController.text));
|
UpdateUserInfo(
|
||||||
|
userId: state.user!.id,
|
||||||
|
picture: _imageFile?.path ??
|
||||||
|
state.user!.picture ??
|
||||||
|
'',
|
||||||
|
name: _nameController.text.isEmpty
|
||||||
|
? null
|
||||||
|
: _nameController.text,
|
||||||
|
nickname:
|
||||||
|
_nameController.text.trim().toLowerCase(),
|
||||||
|
email: _emailController.text.isEmpty
|
||||||
|
? null
|
||||||
|
: _emailController.text,
|
||||||
|
phone: _phoneController.text.isEmpty
|
||||||
|
? null
|
||||||
|
: _phoneController.text,
|
||||||
|
birthDate: _birthDateController.text,
|
||||||
|
gender: _genderController.text,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: const Text('Guardar'),
|
child: const Text('Guardar'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return const Center(child: CircularProgressIndicator());
|
return const Center(child: CircularProgressIndicator());
|
||||||
|
|||||||
@@ -19,7 +19,14 @@ class FirebaseUserRepository implements UserRepository {
|
|||||||
FirebaseUserRepository(this._firebaseAuth) {
|
FirebaseUserRepository(this._firebaseAuth) {
|
||||||
_firebaseAuth.userChanges().listen((user) async {
|
_firebaseAuth.userChanges().listen((user) async {
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
await updateFromFirebase(user.uid);
|
await updateFromFirebase2(
|
||||||
|
userId: user.uid,
|
||||||
|
email: user.email,
|
||||||
|
name: user.displayName,
|
||||||
|
phone: user.phoneNumber,
|
||||||
|
picture: user.photoURL,
|
||||||
|
nickname: user.displayName?.trim().toLowerCase(),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
_userStreamController.add(null);
|
_userStreamController.add(null);
|
||||||
}
|
}
|
||||||
@@ -27,17 +34,35 @@ class FirebaseUserRepository implements UserRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateFromFirebase(String userId) async {
|
Future<void> updateFromFirebase(String userId) async {
|
||||||
try {
|
return updateFromFirebase2(userId: userId);
|
||||||
final myUser = await getMyUser(userId);
|
|
||||||
_userStreamController.add(myUser);
|
|
||||||
} catch (e) {
|
|
||||||
try {
|
|
||||||
await createUser(userId);
|
|
||||||
final myUser = await getMyUser(userId);
|
|
||||||
_userStreamController.add(myUser);
|
|
||||||
} catch (e) {
|
|
||||||
_userStreamController.add(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> updateFromFirebase2({
|
||||||
|
required String userId,
|
||||||
|
String? email,
|
||||||
|
String? name,
|
||||||
|
String? phone,
|
||||||
|
String? picture,
|
||||||
|
String? nickname,
|
||||||
|
}) async {
|
||||||
|
try {
|
||||||
|
var myUser = await getMyUser(userId);
|
||||||
|
|
||||||
|
if (myUser == null) {
|
||||||
|
await createUser(MyUser(
|
||||||
|
id: userId,
|
||||||
|
email: email,
|
||||||
|
name: name,
|
||||||
|
phone: phone,
|
||||||
|
picture: picture,
|
||||||
|
nickname: name?.trim().toLowerCase(),
|
||||||
|
));
|
||||||
|
myUser = await getMyUser(userId);
|
||||||
|
}
|
||||||
|
_userStreamController.add(myUser);
|
||||||
|
} catch (e) {
|
||||||
|
log('xd -- Error updating from firebase ${e.toString()}');
|
||||||
|
_userStreamController.add(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,12 +80,13 @@ class FirebaseUserRepository implements UserRepository {
|
|||||||
@override
|
@override
|
||||||
Future<MyUser> signUp(MyUser myUser, String password) async {
|
Future<MyUser> signUp(MyUser myUser, String password) async {
|
||||||
try {
|
try {
|
||||||
UserCredential user = await _firebaseAuth.createUserWithEmailAndPassword(
|
UserCredential userCredential =
|
||||||
|
await _firebaseAuth.createUserWithEmailAndPassword(
|
||||||
email: myUser.email!,
|
email: myUser.email!,
|
||||||
password: password,
|
password: password,
|
||||||
);
|
);
|
||||||
|
|
||||||
myUser = myUser.copyWith(id: user.user!.uid);
|
myUser = myUser.copyWith(id: userCredential.user!.uid);
|
||||||
|
|
||||||
return myUser;
|
return myUser;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -102,6 +128,14 @@ class FirebaseUserRepository implements UserRepository {
|
|||||||
var credentials = await _firebaseAuth.signInWithCredential(
|
var credentials = await _firebaseAuth.signInWithCredential(
|
||||||
PhoneAuthProvider.credential(
|
PhoneAuthProvider.credential(
|
||||||
verificationId: verificationId, smsCode: code));
|
verificationId: verificationId, smsCode: code));
|
||||||
|
|
||||||
|
if (credentials.user == null) {
|
||||||
|
await setUserData(MyUser(
|
||||||
|
id: credentials.user?.uid ?? '',
|
||||||
|
phone: credentials.user?.phoneNumber ?? '',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
return credentials.user != null ? true : false;
|
return credentials.user != null ? true : false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e is FirebaseAuthException) {
|
if (e is FirebaseAuthException) {
|
||||||
@@ -165,11 +199,16 @@ class FirebaseUserRepository implements UserRepository {
|
|||||||
|
|
||||||
// Get user data
|
// Get user data
|
||||||
@override
|
@override
|
||||||
Future<MyUser> getMyUser(String myUserId) async {
|
Future<MyUser?> getMyUser(String myUserId) async {
|
||||||
try {
|
try {
|
||||||
return usersCollection.doc(myUserId).get().then((value) {
|
return usersCollection.doc(myUserId).get().then((value) {
|
||||||
|
final valueData = value.data();
|
||||||
|
if (valueData == null || valueData.isEmpty || !value.exists) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return MyUser.fromEntity(
|
return MyUser.fromEntity(
|
||||||
MyUserEntity.fromDocument(value.data()!),
|
MyUserEntity.fromDocument(valueData),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -179,8 +218,22 @@ class FirebaseUserRepository implements UserRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> updateUserInfo(String userId, Map<String, dynamic> data) async {
|
Future<void> updateUserInfo(
|
||||||
|
String userId, String? picture, Map<String, dynamic> data) async {
|
||||||
try {
|
try {
|
||||||
|
if (picture != null) {
|
||||||
|
File imageFile = File(picture);
|
||||||
|
Reference firebaseStoreRef =
|
||||||
|
FirebaseStorage.instance.ref().child('$userId/PP/${userId}_lead');
|
||||||
|
|
||||||
|
await firebaseStoreRef.putFile(
|
||||||
|
imageFile,
|
||||||
|
);
|
||||||
|
|
||||||
|
String url = await firebaseStoreRef.getDownloadURL();
|
||||||
|
await usersCollection.doc(userId).update({'picture': url});
|
||||||
|
}
|
||||||
|
|
||||||
await usersCollection.doc(userId).update(data);
|
await usersCollection.doc(userId).update(data);
|
||||||
|
|
||||||
await updateFromFirebase(userId);
|
await updateFromFirebase(userId);
|
||||||
@@ -209,16 +262,9 @@ class FirebaseUserRepository implements UserRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> createUser(String userId) async {
|
Future<void> createUser(MyUser myUser) async {
|
||||||
try {
|
try {
|
||||||
await usersCollection.doc(userId).set({
|
await usersCollection.doc(myUser.id).set(myUser.toEntity().toDocument());
|
||||||
'id': userId,
|
|
||||||
'name': '',
|
|
||||||
'nickname': '',
|
|
||||||
'email': '',
|
|
||||||
'phone': '',
|
|
||||||
'picture': '',
|
|
||||||
});
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e.toString());
|
log(e.toString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,12 @@ abstract class UserRepository {
|
|||||||
|
|
||||||
Future<void> setUserData(MyUser user);
|
Future<void> setUserData(MyUser user);
|
||||||
|
|
||||||
Future<MyUser> getMyUser(String myUserId);
|
Future<MyUser?> getMyUser(String myUserId);
|
||||||
|
|
||||||
Future<void> updateUserInfo(String userId, Map<String, dynamic> data);
|
Future<void> updateUserInfo(
|
||||||
|
String userId, String picture, Map<String, dynamic> data);
|
||||||
|
|
||||||
Future<String> uploadPicture(String file, String userId);
|
Future<String> uploadPicture(String file, String userId);
|
||||||
|
|
||||||
Future<void> createUser(String userId);
|
Future<void> createUser(MyUser myUser);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user