chore: remove Firebase dependencies and legacy code (Fase 4)
- Delete all firebase_*_repository.dart files (replaced by api_* equivalents) - Remove cloud_firestore, firebase_auth, firebase_storage, firebase_core from all package pubspecs - Remove cloud_firestore from main pubspec.yaml - Delete firebase_options.dart (no longer referenced) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
733384091c
commit
af91e0ba04
@@ -1,89 +0,0 @@
|
||||
// File generated by FlutterFire CLI.
|
||||
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
|
||||
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
|
||||
import 'package:flutter/foundation.dart'
|
||||
show defaultTargetPlatform, kIsWeb, TargetPlatform;
|
||||
|
||||
/// Default [FirebaseOptions] for use with your Firebase apps.
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// import 'firebase_options.dart';
|
||||
/// // ...
|
||||
/// await Firebase.initializeApp(
|
||||
/// options: DefaultFirebaseOptions.currentPlatform,
|
||||
/// );
|
||||
/// ```
|
||||
class DefaultFirebaseOptions {
|
||||
static FirebaseOptions get currentPlatform {
|
||||
if (kIsWeb) {
|
||||
return web;
|
||||
}
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
return android;
|
||||
case TargetPlatform.iOS:
|
||||
return ios;
|
||||
case TargetPlatform.macOS:
|
||||
return macos;
|
||||
case TargetPlatform.windows:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for windows - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
case TargetPlatform.linux:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for linux - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
default:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions are not supported for this platform.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static const FirebaseOptions web = FirebaseOptions(
|
||||
apiKey: 'AIzaSyCNpUV_4cMEL9QZx7NESXK7QAlRjRGwx_Y',
|
||||
appId: '1:245204384533:web:1b8f0b4c1d9ae21d9f871c',
|
||||
messagingSenderId: '245204384533',
|
||||
projectId: 'prosapp-5747a',
|
||||
authDomain: 'prosapp-5747a.firebaseapp.com',
|
||||
databaseURL: 'https://prosapp-5747a-default-rtdb.firebaseio.com',
|
||||
storageBucket: 'prosapp-5747a.appspot.com',
|
||||
measurementId: 'G-EVBEQRZEDY',
|
||||
);
|
||||
|
||||
static const FirebaseOptions android = FirebaseOptions(
|
||||
apiKey: 'AIzaSyBp7vsJvD6oXz0FORBLEeIELwId4a2onHQ',
|
||||
appId: '1:245204384533:android:e01772831d86f5c79f871c',
|
||||
messagingSenderId: '245204384533',
|
||||
projectId: 'prosapp-5747a',
|
||||
databaseURL: 'https://prosapp-5747a-default-rtdb.firebaseio.com',
|
||||
storageBucket: 'prosapp-5747a.appspot.com',
|
||||
);
|
||||
|
||||
static const FirebaseOptions ios = FirebaseOptions(
|
||||
apiKey: 'AIzaSyDUhnkNkeEPkqcwVo5EWr63q3oEX6bDGic',
|
||||
appId: '1:245204384533:ios:1d58f5624d0df4859f871c',
|
||||
messagingSenderId: '245204384533',
|
||||
projectId: 'prosapp-5747a',
|
||||
databaseURL: 'https://prosapp-5747a-default-rtdb.firebaseio.com',
|
||||
storageBucket: 'prosapp-5747a.appspot.com',
|
||||
androidClientId: '245204384533-04oabs744hp8fjbdreijp4h16nvfmeti.apps.googleusercontent.com',
|
||||
iosClientId: '245204384533-nv7e2n7d4vj5kfkc55mlmiiju0ch2qhn.apps.googleusercontent.com',
|
||||
iosBundleId: 'com.example.prosappco',
|
||||
);
|
||||
|
||||
static const FirebaseOptions macos = FirebaseOptions(
|
||||
apiKey: 'AIzaSyDUhnkNkeEPkqcwVo5EWr63q3oEX6bDGic',
|
||||
appId: '1:245204384533:ios:1d58f5624d0df4859f871c',
|
||||
messagingSenderId: '245204384533',
|
||||
projectId: 'prosapp-5747a',
|
||||
databaseURL: 'https://prosapp-5747a-default-rtdb.firebaseio.com',
|
||||
storageBucket: 'prosapp-5747a.appspot.com',
|
||||
androidClientId: '245204384533-04oabs744hp8fjbdreijp4h16nvfmeti.apps.googleusercontent.com',
|
||||
iosClientId: '245204384533-nv7e2n7d4vj5kfkc55mlmiiju0ch2qhn.apps.googleusercontent.com',
|
||||
iosBundleId: 'com.example.prosappco',
|
||||
);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:chat_repository/chat_repository.dart';
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
class FirebaseChatRepository {
|
||||
final chatCollection = FirebaseFirestore.instance.collection('chats');
|
||||
|
||||
Stream<ChatEntity?> getChatById(String chatId) {
|
||||
return chatCollection.doc(chatId).snapshots().map((snapshot) {
|
||||
try {
|
||||
if (snapshot.exists) {
|
||||
return ChatEntity.fromDocument(snapshot.data()!);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<ChatEntity> createNewChat(
|
||||
String chatId, String userId, String professionalId) async {
|
||||
ChatEntity chat = ChatEntity(
|
||||
id: chatId,
|
||||
userId: userId,
|
||||
professionalId: professionalId,
|
||||
messages: const [],
|
||||
);
|
||||
|
||||
await chatCollection.doc(chatId).set(chat.toDocument());
|
||||
|
||||
return chat;
|
||||
}
|
||||
|
||||
sendMessage(String chatId, MessageEntity message) {
|
||||
chatCollection.doc(chatId).update({
|
||||
'messages': FieldValue.arrayUnion([message.toDocument()])
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,6 @@ dependencies:
|
||||
http: ^1.1.0
|
||||
shared_preferences: ^2.0.10
|
||||
|
||||
# Firebase kept for FirebaseChatRepository (legacy fallback)
|
||||
cloud_firestore: ^4.15.4
|
||||
firebase_core: ^2.25.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^2.0.0
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:city_repository/city_repository.dart';
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
class FirebaseCityRepository implements CityRepository {
|
||||
final citiesCollection = FirebaseFirestore.instance.collection('countries v2');
|
||||
|
||||
List<CityUi>? _cities;
|
||||
|
||||
@override
|
||||
Future<List<CityUi>> getCities() async {
|
||||
if (_cities != null) {
|
||||
return _cities!;
|
||||
}
|
||||
|
||||
final List<CityUi> cities = [];
|
||||
|
||||
try {
|
||||
final doc = await citiesCollection.doc("Colombia").get();
|
||||
|
||||
final data = doc.data();
|
||||
|
||||
final country = CountryEntity.fromDocument(data as Map<String, dynamic>);
|
||||
|
||||
for (var region in country.regions) {
|
||||
for (var city in region.cities) {
|
||||
cities.add(CityUi(
|
||||
cityName: city.name,
|
||||
coordsOfCity: city.coords,
|
||||
stateOfCity: region.name,
|
||||
countryOfCity: country.name,
|
||||
));
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
|
||||
_cities = cities;
|
||||
return cities;
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,6 @@ dependencies:
|
||||
http: ^1.1.0
|
||||
shared_preferences: ^2.0.10
|
||||
|
||||
# Firebase kept for FirebaseCityRepository (legacy fallback)
|
||||
cloud_firestore: ^4.15.4
|
||||
firebase_core: ^2.25.4
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:profession_repository/profession_repository.dart';
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
class FirebaseProfessionRepository implements ProfessionRepository {
|
||||
final professionsCollection =
|
||||
FirebaseFirestore.instance.collection('professions');
|
||||
|
||||
@override
|
||||
Future<Professions> getProfessions() async {
|
||||
try {
|
||||
final doc = await professionsCollection.doc("professions").get();
|
||||
return Professions.fromDocument(doc.data() as Map<String, dynamic>);
|
||||
} catch (e) {
|
||||
log('Error getting documents: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Professions {
|
||||
final List<String> professions;
|
||||
|
||||
Professions(this.professions);
|
||||
|
||||
factory Professions.fromDocument(Map<String, dynamic> json) {
|
||||
return Professions(List<String>.from(json['professions']));
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,6 @@ dependencies:
|
||||
http: ^1.1.0
|
||||
shared_preferences: ^2.0.10
|
||||
|
||||
# Firebase kept for FirebaseProfessionRepository (legacy fallback)
|
||||
cloud_firestore: ^4.15.4
|
||||
firebase_core: ^2.25.4
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
-213
@@ -1,213 +0,0 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:professional_repository/professional_repository.dart';
|
||||
import 'package:firebase_storage/firebase_storage.dart';
|
||||
|
||||
class FirebaseProfessionalRepository {
|
||||
final professionalCollection =
|
||||
FirebaseFirestore.instance.collection('professional_info');
|
||||
|
||||
ProfessionalEntity? _proInfo;
|
||||
final StreamController<ProfessionalEntity?> _proInfoBroadcast =
|
||||
StreamController<ProfessionalEntity?>.broadcast();
|
||||
|
||||
bool isProModeActive = false;
|
||||
|
||||
final StreamController<bool> _isProModeActiveBroadcast =
|
||||
StreamController.broadcast();
|
||||
|
||||
FirebaseProfessionalRepository() {
|
||||
_isProModeActiveBroadcast.add(isProModeActive);
|
||||
|
||||
FirebaseAuth.instance.userChanges().listen((user) async {
|
||||
if (user != null) {
|
||||
await updateFromFirebase(
|
||||
userId: user.uid,
|
||||
);
|
||||
} else {
|
||||
_proInfo = null;
|
||||
_proInfoBroadcast.add(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ProfessionalEntity? lastProInfo() {
|
||||
return _proInfo;
|
||||
}
|
||||
|
||||
Stream<ProfessionalEntity?> streamProInfo() {
|
||||
return _proInfoBroadcast.stream;
|
||||
}
|
||||
|
||||
Future<void> updateFromFirebase({
|
||||
required String userId,
|
||||
}) async {
|
||||
try {
|
||||
final proInfo = await getProInfo(userId);
|
||||
_proInfo = proInfo;
|
||||
_proInfoBroadcast.add(proInfo);
|
||||
} catch (e) {
|
||||
_proInfo = null;
|
||||
_proInfoBroadcast.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
Future<ProfessionalEntity?> getProInfo(String myUserId) async {
|
||||
try {
|
||||
return professionalCollection.doc(myUserId).get().then((value) {
|
||||
final valueData = value.data();
|
||||
if (valueData == null || valueData.isEmpty || !value.exists) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ProfessionalEntity.fromDocument(valueData);
|
||||
});
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Stream<bool> sreamIsProModeActive() {
|
||||
return _isProModeActiveBroadcast.stream;
|
||||
}
|
||||
|
||||
switchProMode() async {
|
||||
isProModeActive = !isProModeActive;
|
||||
_isProModeActiveBroadcast.add(isProModeActive);
|
||||
}
|
||||
|
||||
Future<void> updateProfessionalInfo(
|
||||
String address,
|
||||
String aditionalAddress,
|
||||
bool ratePreferences,
|
||||
String rate,
|
||||
LocationPreferences locationPreferences,
|
||||
double latitude,
|
||||
double longitude,
|
||||
Schedules schedules,
|
||||
PaymentMethodEntity paymentMethods,
|
||||
) async {
|
||||
if (_proInfo == null) {
|
||||
log('_proInfo is null');
|
||||
return;
|
||||
}
|
||||
await professionalCollection.doc(_proInfo!.id).update({
|
||||
'address': address,
|
||||
'aditional_address': aditionalAddress,
|
||||
'rate_preferences': ratePreferences,
|
||||
'rate': rate,
|
||||
'location_preferences': enumToInt(locationPreferences),
|
||||
'latitude': latitude,
|
||||
'longitude': longitude,
|
||||
'schedules': schedules.toJson(),
|
||||
'payment_methods': paymentMethods.toDocument(),
|
||||
});
|
||||
|
||||
await updateFromFirebase(userId: _proInfo!.id);
|
||||
}
|
||||
|
||||
Future<void> saveProfessionalInfo(ProfessionalEntity entity) async {
|
||||
await professionalCollection.doc(entity.id).set(entity.toDocument());
|
||||
}
|
||||
|
||||
Future<void> uploadBannerPicture(String file) async {
|
||||
try {
|
||||
File imageFile = File(file);
|
||||
Reference firebaseStoreRef = FirebaseStorage.instance
|
||||
.ref()
|
||||
.child('${_proInfo!.id}/BN/${_proInfo!.id}_banner');
|
||||
await firebaseStoreRef.putFile(imageFile);
|
||||
String url = await firebaseStoreRef.getDownloadURL();
|
||||
|
||||
await professionalCollection
|
||||
.doc(_proInfo!.id)
|
||||
.update({'banner_picture': url});
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> uploadPdfCedula(String file, String userId) async {
|
||||
try {
|
||||
File pdfFile = File(file);
|
||||
Reference firebaseStoreRef = FirebaseStorage.instance
|
||||
.ref()
|
||||
.child('$userId/PDF/${userId}_cedula.pdf');
|
||||
await firebaseStoreRef.putFile(pdfFile);
|
||||
String url = await firebaseStoreRef.getDownloadURL();
|
||||
return url;
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> uploadPdfCertificado(String file, String userId) async {
|
||||
try {
|
||||
File pdfFile = File(file);
|
||||
Reference firebaseStoreRef = FirebaseStorage.instance
|
||||
.ref()
|
||||
.child('$userId/PDF/${userId}_certificado.pdf');
|
||||
await firebaseStoreRef.putFile(pdfFile);
|
||||
String url = await firebaseStoreRef.getDownloadURL();
|
||||
return url;
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<String>> uploadPdfsEspecializaciones(
|
||||
List<String> files, String userId) async {
|
||||
try {
|
||||
List<String> urls = [];
|
||||
for (String file in files) {
|
||||
File pdfFile = File(file);
|
||||
Reference firebaseStoreRef = FirebaseStorage.instance.ref().child(
|
||||
'$userId/PDF/${userId}_${DateTime.now().millisecondsSinceEpoch}_especializacion.pdf');
|
||||
await firebaseStoreRef.putFile(pdfFile);
|
||||
String url = await firebaseStoreRef.getDownloadURL();
|
||||
urls.add(url);
|
||||
}
|
||||
return urls;
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<ProfessionalEntity>> getProfessionalInfo() async {
|
||||
try {
|
||||
QuerySnapshot<Map<String, dynamic>> querySnapshot =
|
||||
await professionalCollection.get();
|
||||
return querySnapshot.docs
|
||||
.map((e) => ProfessionalEntity.fromDocument(e.data()))
|
||||
.toList();
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<ProfessionalEntity>> getProfessionalsFromIds(
|
||||
Iterable<String> ids) async {
|
||||
try {
|
||||
final querySnapshot = await professionalCollection
|
||||
.where(FieldPath.documentId, whereIn: ids)
|
||||
.get();
|
||||
|
||||
return querySnapshot.docs
|
||||
.map((e) => ProfessionalEntity.fromDocument(e.data()))
|
||||
.toList();
|
||||
} catch (e) {
|
||||
log('getProfessionsFromIds ${e.toString()}');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,11 +15,6 @@ dependencies:
|
||||
shared_preferences: ^2.0.10
|
||||
intl: ^0.19.0
|
||||
|
||||
# Firebase kept for FirebaseProfessionalRepository (legacy fallback)
|
||||
cloud_firestore: ^4.15.4
|
||||
firebase_storage: ^11.6.5
|
||||
firebase_core: ^2.25.4
|
||||
firebase_auth: ^4.17.8
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^2.0.0
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:score_repository/score_repository.dart';
|
||||
import 'package:score_repository/src/entities/comment_entity.dart';
|
||||
|
||||
class FirebaseScoreRepository {
|
||||
final reputationsCollection =
|
||||
FirebaseFirestore.instance.collection('reputations');
|
||||
|
||||
final commentsCollection = FirebaseFirestore.instance.collection('comments');
|
||||
|
||||
ReputationEntity? _reputation;
|
||||
final StreamController<ReputationEntity> _reputationController =
|
||||
StreamController<ReputationEntity>.broadcast();
|
||||
|
||||
Stream<ReputationEntity> streamReputation() {
|
||||
return _reputationController.stream;
|
||||
}
|
||||
|
||||
FirebaseScoreRepository() {
|
||||
FirebaseAuth.instance.userChanges().listen((user) async {
|
||||
if (user != null) {
|
||||
final reputation = await getReputationByUserId(user.uid);
|
||||
_reputation = reputation;
|
||||
} else {
|
||||
_reputation = null;
|
||||
}
|
||||
_reputationController.add(_reputation ??
|
||||
const ReputationEntity(
|
||||
total: 0,
|
||||
average: 0,
|
||||
totalPro: 0,
|
||||
averagePro: 0,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
ReputationEntity getReputation() {
|
||||
return _reputation ??
|
||||
const ReputationEntity(
|
||||
total: 0,
|
||||
average: 0,
|
||||
totalPro: 0,
|
||||
averagePro: 0,
|
||||
);
|
||||
}
|
||||
|
||||
Future<ReputationEntity> getReputationByUserId(String userId) async {
|
||||
try {
|
||||
final snap = await reputationsCollection.doc(userId).get();
|
||||
return ReputationEntity.fromDocument(snap.data()!);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
return const ReputationEntity(
|
||||
total: 0,
|
||||
average: 0,
|
||||
totalPro: 0,
|
||||
averagePro: 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Stream<List<CommentEntity>> getScoresForUser(String userId) {
|
||||
return commentsCollection
|
||||
.where('destination_id', isEqualTo: userId)
|
||||
.where('is_from_user', isEqualTo: false)
|
||||
.snapshots()
|
||||
.map((querySnapshot) => querySnapshot.docs
|
||||
.map((doc) => CommentEntity.fromDocument(doc.data()))
|
||||
.toList());
|
||||
}
|
||||
|
||||
Stream<List<CommentEntity>> getScoresForProfessional(String userId) {
|
||||
return commentsCollection
|
||||
.where('destination_id', isEqualTo: userId)
|
||||
.where('is_from_user', isEqualTo: true)
|
||||
.snapshots()
|
||||
.map((querySnapshot) => querySnapshot.docs
|
||||
.map((doc) => CommentEntity.fromDocument(doc.data()))
|
||||
.toList());
|
||||
}
|
||||
|
||||
addComment(CommentEntity comment) async {
|
||||
await commentsCollection.add(comment.toDocument());
|
||||
|
||||
final query = await commentsCollection
|
||||
.where('destination_id', isEqualTo: comment.destinationId)
|
||||
.where('is_from_user', isEqualTo: comment.isFromUser)
|
||||
.get();
|
||||
|
||||
var total = 0.0;
|
||||
var count = 0;
|
||||
for (var doc in query.docs) {
|
||||
final comment = CommentEntity.fromDocument(doc.data());
|
||||
total += comment.score;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
final average = total / count;
|
||||
if (comment.isFromUser) {
|
||||
await reputationsCollection.doc(comment.destinationId).set(
|
||||
{'total_pro': count, 'average_pro': average},
|
||||
SetOptions(merge: true));
|
||||
} else {
|
||||
await reputationsCollection.doc(comment.destinationId).set({
|
||||
'total': count,
|
||||
'average': average,
|
||||
}, SetOptions(merge: true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,6 @@ dependencies:
|
||||
http: ^1.1.0
|
||||
shared_preferences: ^2.0.10
|
||||
|
||||
# Firebase kept for FirebaseScoreRepository (legacy) and CommentEntity uses Timestamp
|
||||
cloud_firestore: ^4.15.4
|
||||
firebase_core: ^2.25.4
|
||||
firebase_auth: ^4.17.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^2.0.0
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:service_repository/service_repository.dart';
|
||||
|
||||
class FirebaseServiceRepository {
|
||||
final serviceCollection = FirebaseFirestore.instance.collection('services');
|
||||
|
||||
Future<String> createService(ServiceEntity entity) async {
|
||||
DocumentReference<Map<String, dynamic>> docRef =
|
||||
await serviceCollection.add(entity.toDocument());
|
||||
return docRef.id;
|
||||
}
|
||||
|
||||
Future<void> updateServiceStatus(
|
||||
String serviceId, ServiceStatus newStatus) async {
|
||||
await serviceCollection
|
||||
.doc(serviceId)
|
||||
.update({'status': enumToIntService(newStatus)});
|
||||
}
|
||||
|
||||
Stream<ServiceEntity> getService(String serviceId) {
|
||||
return serviceCollection.doc(serviceId).snapshots().map((snapshot) {
|
||||
if (snapshot.exists) {
|
||||
return ServiceEntity.fromDocument(snapshot.data()!, snapshot.id);
|
||||
} else {
|
||||
throw Exception('El servicio con ID $serviceId no existe');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Stream<List<ServiceEntity>> getServicesForUser(String userId) {
|
||||
return serviceCollection
|
||||
.where('user_id', isEqualTo: userId)
|
||||
.where('status', whereIn: [0, 1, 3])
|
||||
.snapshots()
|
||||
.map((querySnapshot) => querySnapshot.docs
|
||||
.map((doc) => ServiceEntity.fromDocument(doc.data(), doc.id))
|
||||
.toList());
|
||||
}
|
||||
|
||||
Stream<List<ServiceEntity>> getServicesForProfessional(
|
||||
String professionalId) {
|
||||
return serviceCollection
|
||||
.where('professional_id', isEqualTo: professionalId)
|
||||
.where('status', whereIn: [1, 3])
|
||||
.snapshots()
|
||||
.map((querySnapshot) => querySnapshot.docs
|
||||
.map((doc) => ServiceEntity.fromDocument(doc.data(), doc.id))
|
||||
.toList());
|
||||
}
|
||||
|
||||
Future<List<ServiceEntity>> getServicesForProfessionalforCalendar(
|
||||
String professionalId) async {
|
||||
QuerySnapshot<Map<String, dynamic>> query = await serviceCollection
|
||||
.where('professional_id', isEqualTo: professionalId)
|
||||
.where('status', whereIn: [0, 1, 2, 3, 6]).get();
|
||||
|
||||
return query.docs
|
||||
.map((doc) => ServiceEntity.fromDocument(doc.data(), doc.id))
|
||||
.toList();
|
||||
}
|
||||
|
||||
Stream<List<ServiceEntity>> getServicesHistoryForUser(String userId) {
|
||||
return serviceCollection
|
||||
.where('user_id', isEqualTo: userId)
|
||||
.where('status', whereIn: [2, 4, 5])
|
||||
.snapshots()
|
||||
.map((querySnapshot) => querySnapshot.docs
|
||||
.map((doc) => ServiceEntity.fromDocument(doc.data(), doc.id))
|
||||
.toList());
|
||||
}
|
||||
|
||||
Stream<List<ServiceEntity>> getServicesHistoryForProfessional(
|
||||
String professionalId) {
|
||||
return serviceCollection
|
||||
.where('professional_id', isEqualTo: professionalId)
|
||||
.where('status', whereIn: [2, 4, 5])
|
||||
.snapshots()
|
||||
.map((querySnapshot) => querySnapshot.docs
|
||||
.map((doc) => ServiceEntity.fromDocument(doc.data(), doc.id))
|
||||
.toList());
|
||||
}
|
||||
|
||||
Stream<List<ServiceEntity>> getPendingServicesForProfessional(String professionalId) {
|
||||
return serviceCollection
|
||||
.where('professional_id', isEqualTo: professionalId)
|
||||
.where('status', whereIn: [0])
|
||||
.snapshots()
|
||||
.map((querySnapshot) => querySnapshot.docs
|
||||
.map((doc) => ServiceEntity.fromDocument(doc.data(), doc.id))
|
||||
.toList());
|
||||
}
|
||||
|
||||
Future<int> countPendingServicesForProfessional(String professionalId) async {
|
||||
QuerySnapshot<Map<String, dynamic>> query = await serviceCollection
|
||||
.where('professional_id', isEqualTo: professionalId)
|
||||
.where('status', isEqualTo: 0)
|
||||
.get();
|
||||
|
||||
return query.size;
|
||||
}
|
||||
|
||||
// actualizar professionalScored a true
|
||||
Future<void> setProfessionalScored(String serviceId) {
|
||||
return serviceCollection
|
||||
.doc(serviceId)
|
||||
.update({'professional_scored': true});
|
||||
}
|
||||
|
||||
Future<void> setUserScored(String serviceId) {
|
||||
return serviceCollection.doc(serviceId).update({'user_scored': true});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 0 - pending
|
||||
// 1 - acepted
|
||||
// 2 - denied
|
||||
// 3 - active
|
||||
// 4 - cancelled
|
||||
// 5 - completed
|
||||
@@ -14,9 +14,6 @@ dependencies:
|
||||
http: ^1.1.0
|
||||
shared_preferences: ^2.0.10
|
||||
|
||||
# Firebase kept for FirebaseServiceRepository (legacy) and ServiceEntity uses Timestamp
|
||||
cloud_firestore: ^4.15.4
|
||||
firebase_core: ^2.25.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^2.0.0
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import 'package:setting_repository/src/entities/entities.dart';
|
||||
import 'package:setting_repository/src/repositories/setting_repo.dart';
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
class FirebaseSettingRepository implements SettingRepository {
|
||||
final settingsCollection = FirebaseFirestore.instance.collection('settings');
|
||||
|
||||
@override
|
||||
Future<SettingEntity> getSettings() async {
|
||||
final DocumentSnapshot doc = await settingsCollection.doc('global').get();
|
||||
|
||||
return SettingEntity.fromDocument(doc.data() as Map<String, dynamic>);
|
||||
}
|
||||
}
|
||||
@@ -14,9 +14,6 @@ dependencies:
|
||||
http: ^1.1.0
|
||||
shared_preferences: ^2.0.10
|
||||
|
||||
# Firebase kept for FirebaseSettingRepository (legacy fallback)
|
||||
cloud_firestore: ^4.15.4
|
||||
firebase_core: ^2.25.4
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
@@ -1,421 +0,0 @@
|
||||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:firebase_storage/firebase_storage.dart';
|
||||
import 'package:user_repository/src/models/models.dart';
|
||||
import '../entities/entities.dart';
|
||||
import 'user_repo.dart';
|
||||
|
||||
class FirebaseUserRepository implements UserRepository {
|
||||
MyUser? _lastUser;
|
||||
|
||||
final FirebaseAuth _firebaseAuth;
|
||||
final usersCollection = FirebaseFirestore.instance.collection('users');
|
||||
final StreamController<MyUser?> _userStreamController =
|
||||
StreamController<MyUser?>.broadcast();
|
||||
String verificationId = '';
|
||||
|
||||
FirebaseUserRepository(this._firebaseAuth) {
|
||||
_firebaseAuth.userChanges().listen((user) async {
|
||||
if (user != null) {
|
||||
await updateFromFirebase2(
|
||||
userId: user.uid,
|
||||
email: user.email,
|
||||
name: user.displayName,
|
||||
phone: user.phoneNumber,
|
||||
picture: user.photoURL,
|
||||
nickname: user.displayName?.trim().toLowerCase(),
|
||||
);
|
||||
} else {
|
||||
_lastUser = null;
|
||||
_userStreamController.add(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MyUser?> lastUser() async {
|
||||
return _lastUser;
|
||||
}
|
||||
|
||||
Future<void> refreshUser() async {
|
||||
final user = _firebaseAuth.currentUser;
|
||||
if (user != null) {
|
||||
await updateFromFirebase(user.uid);
|
||||
} else {
|
||||
_lastUser = null;
|
||||
_userStreamController.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateFromFirebase(String userId) async {
|
||||
return updateFromFirebase2(userId: userId);
|
||||
}
|
||||
|
||||
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(),
|
||||
proState: ProState.inactive,
|
||||
));
|
||||
myUser = await getMyUser(userId);
|
||||
}
|
||||
_lastUser = myUser;
|
||||
_userStreamController.add(myUser);
|
||||
} catch (e) {
|
||||
log('xd -- Error updating from firebase ${e.toString()}');
|
||||
_lastUser = null;
|
||||
_userStreamController.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<MyUser?> streamUser() {
|
||||
return _userStreamController.stream;
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<bool> isAuthenticated() {
|
||||
return _firebaseAuth.userChanges().map((event) => null != event);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MyUser> signUp(MyUser myUser, String password) async {
|
||||
try {
|
||||
UserCredential userCredential =
|
||||
await _firebaseAuth.createUserWithEmailAndPassword(
|
||||
email: myUser.email!,
|
||||
password: password,
|
||||
);
|
||||
|
||||
myUser = myUser.copyWith(id: userCredential.user!.uid);
|
||||
|
||||
return myUser;
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> signInWithPhoneNumber(String phoneNumber) async {
|
||||
try {
|
||||
await _firebaseAuth.verifyPhoneNumber(
|
||||
phoneNumber: phoneNumber,
|
||||
verificationCompleted: (PhoneAuthCredential credential) async {
|
||||
await _firebaseAuth.signInWithCredential(credential);
|
||||
},
|
||||
codeSent: (String verificationId, int? resendToken) {
|
||||
this.verificationId = verificationId;
|
||||
},
|
||||
codeAutoRetrievalTimeout: (String verificationId) {
|
||||
this.verificationId = verificationId;
|
||||
},
|
||||
verificationFailed: (FirebaseAuthException e) {
|
||||
if (e.code == 'invalid-phone-number') {
|
||||
} else if (e.code == 'network-request-failed') {
|
||||
} else {}
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> verifyOTP(String code) async {
|
||||
try {
|
||||
var credentials = await _firebaseAuth.signInWithCredential(
|
||||
PhoneAuthProvider.credential(
|
||||
verificationId: verificationId, smsCode: code));
|
||||
|
||||
if (credentials.user == null) {
|
||||
await setUserData(MyUser(
|
||||
id: credentials.user?.uid ?? '',
|
||||
phone: credentials.user?.phoneNumber ?? '',
|
||||
proState: ProState.inactive,
|
||||
));
|
||||
}
|
||||
|
||||
return credentials.user != null ? true : false;
|
||||
} catch (e) {
|
||||
if (e is FirebaseAuthException) {
|
||||
if (e.code == 'invalid-verification-code') {
|
||||
return false;
|
||||
} else {
|
||||
rethrow;
|
||||
}
|
||||
} else {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> signIn(String email, String password) async {
|
||||
try {
|
||||
await _firebaseAuth.signInWithEmailAndPassword(
|
||||
email: email,
|
||||
password: password,
|
||||
);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String?> addEmailAndPassword(String email, String password) async {
|
||||
try {
|
||||
await _firebaseAuth.currentUser!.updateEmail(email);
|
||||
await _firebaseAuth.currentUser!.updatePassword(password);
|
||||
|
||||
final user = await getMyUser(_firebaseAuth.currentUser!.uid);
|
||||
if (user == null) {
|
||||
return "user-not-found";
|
||||
}
|
||||
|
||||
final newUser = user.copyWith(email: email);
|
||||
await updateUserInfo(newUser);
|
||||
|
||||
return null;
|
||||
} catch (e) {
|
||||
if (e is FirebaseAuthException && e.code == 'requires-recent-login') {
|
||||
return 'requires-recent-login';
|
||||
}
|
||||
|
||||
if (e is FirebaseAuthException && e.code == 'email-already-in-use') {
|
||||
return 'email-already-in-use';
|
||||
}
|
||||
|
||||
return 'unknown-error';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
addPhoneAuthCredential(String password, String phoneNumber,
|
||||
{required Future<void> Function(Exception) verificationFailed,
|
||||
required Future<void> Function(String) codeSent,
|
||||
required Future<void> Function(String) codeAutoRetrievalTimeout}) async {
|
||||
await _firebaseAuth.verifyPhoneNumber(
|
||||
phoneNumber: phoneNumber,
|
||||
timeout: const Duration(seconds: 60),
|
||||
verificationCompleted: (AuthCredential authCredential) async {
|
||||
// La verificación se completó automáticamente.
|
||||
// TODO: Revisar si es necesario.
|
||||
},
|
||||
verificationFailed: (FirebaseAuthException authException) async {
|
||||
// La verificación falló.
|
||||
// throw authException;
|
||||
log('verificationFailed: $authException');
|
||||
await verificationFailed(authException);
|
||||
},
|
||||
codeAutoRetrievalTimeout: (String verificationId) async {
|
||||
// Tiempo de espera agotado para la recuperación automática del código.
|
||||
// throw 'timeout';
|
||||
log(verificationId);
|
||||
await codeAutoRetrievalTimeout(verificationId);
|
||||
},
|
||||
codeSent: (String verificationId, int? resendToken) async {
|
||||
await codeSent(verificationId);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> linkWithOTP(
|
||||
String phoneNumber, String verificationId, String code) async {
|
||||
try {
|
||||
var phoneAuthCredential = PhoneAuthProvider.credential(
|
||||
verificationId: verificationId, smsCode: code);
|
||||
|
||||
User? userAuth = FirebaseAuth.instance.currentUser;
|
||||
|
||||
if (userAuth == null) {
|
||||
throw 'User not found';
|
||||
}
|
||||
|
||||
final user = await getMyUser(_firebaseAuth.currentUser!.uid);
|
||||
if (user == null) {
|
||||
throw "user-not-found";
|
||||
}
|
||||
|
||||
await userAuth.linkWithCredential(phoneAuthCredential);
|
||||
final newUser = user.copyWith(phone: phoneNumber);
|
||||
await updateUserInfo(newUser);
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (e is FirebaseAuthException) {
|
||||
if (e.code == 'invalid-verification-code') {
|
||||
return false;
|
||||
} else {
|
||||
rethrow;
|
||||
}
|
||||
} else {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<UpdatePassworErros?> updatePassword(
|
||||
String password, String newPassword) async {
|
||||
try {
|
||||
User? user = FirebaseAuth.instance.currentUser;
|
||||
|
||||
if (user == null) {
|
||||
return UpdatePassworErros.userNotFound;
|
||||
}
|
||||
|
||||
// Verificar la autenticación reciente
|
||||
await user.reauthenticateWithCredential(EmailAuthProvider.credential(
|
||||
email: user.email!,
|
||||
password: password,
|
||||
));
|
||||
|
||||
await _firebaseAuth.currentUser!.updatePassword(newPassword);
|
||||
return null;
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
return UpdatePassworErros.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
// Sign out
|
||||
@override
|
||||
Future<void> logOut() async {
|
||||
try {
|
||||
await _firebaseAuth.signOut();
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> resetPassword(String email) async {
|
||||
try {
|
||||
await _firebaseAuth.sendPasswordResetEmail(email: email);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setUserData(MyUser user) async {
|
||||
try {
|
||||
await usersCollection.doc(user.id).set(user.toEntity().toDocument());
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<MyUser?> getMyUser(String myUserId) async {
|
||||
try {
|
||||
return usersCollection.doc(myUserId).get().then((value) {
|
||||
final valueData = value.data();
|
||||
if (valueData == null || valueData.isEmpty || !value.exists) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return MyUser.fromEntity(
|
||||
MyUserEntity.fromDocument(valueData),
|
||||
);
|
||||
});
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateUserInfo(MyUser myUser) async {
|
||||
try {
|
||||
await usersCollection
|
||||
.doc(myUser.id)
|
||||
.update(myUser.toEntity().toDocument());
|
||||
await updateFromFirebase(myUser.id);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> uploadPicture(String file, String userId) async {
|
||||
try {
|
||||
File imageFile = File(file);
|
||||
Reference firebaseStoreRef =
|
||||
FirebaseStorage.instance.ref().child('$userId/PP/${userId}_lead');
|
||||
await firebaseStoreRef.putFile(imageFile);
|
||||
String url = await firebaseStoreRef.getDownloadURL();
|
||||
return url;
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> createUser(MyUser myUser) async {
|
||||
try {
|
||||
await usersCollection.doc(myUser.id).set(myUser.toEntity().toDocument());
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<MyUser>> getUsersProfessionalActive() async {
|
||||
try {
|
||||
final querySnapshot = await usersCollection
|
||||
.where('professional_state', isEqualTo: ProState.active.index)
|
||||
.get();
|
||||
|
||||
return querySnapshot.docs
|
||||
.map((e) => MyUser.fromEntity(MyUserEntity.fromDocument(e.data())))
|
||||
.toList();
|
||||
} catch (e) {
|
||||
log('xd -- ${e.toString()}');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<MyUser>> getUsersFromIds(Iterable<String> ids) async {
|
||||
try {
|
||||
final querySnapshot =
|
||||
await usersCollection.where(FieldPath.documentId, whereIn: ids).get();
|
||||
|
||||
return querySnapshot.docs
|
||||
.map((e) => MyUser.fromEntity(MyUserEntity.fromDocument(e.data())))
|
||||
.toList();
|
||||
} catch (e) {
|
||||
log('getUsersFromIds ${e.toString()}');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,6 @@ dependencies:
|
||||
http: ^1.1.0
|
||||
shared_preferences: ^2.0.10
|
||||
|
||||
# Firebase kept for FirebaseUserRepository (legacy fallback)
|
||||
firebase_auth: ^4.17.4
|
||||
cloud_firestore: ^4.15.4
|
||||
firebase_storage: ^11.6.5
|
||||
firebase_core: ^2.25.4
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
@@ -15,7 +15,6 @@ dependencies:
|
||||
path: packages/chat_repository
|
||||
city_repository:
|
||||
path: packages/city_repository
|
||||
cloud_firestore: ^4.15.4
|
||||
community_material_icon: ^5.9.55
|
||||
cupertino_icons: ^1.0.2
|
||||
diacritic: ^0.1.5
|
||||
|
||||
Reference in New Issue
Block a user