Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Худшая библиотека из которых я сталкивался
Если честно, то это была версия firebase_auth 4.x с какого-то периода разработки. Расскажу подробнее о проблемах и что я из этого вынес.
Что именно было проблемой
1. Несовместимость версий (Dependency Hell)
dependencies:
firebase_auth: ^4.5.0
firebase_core: ^2.0.0
# Но firebase_auth требует firebase_core: ^1.0.0
# Конфликт!
Обновишь одну зависимость — другая ломается. Это занимало часы на разрешение конфликтов в pubspec.lock.
2. Breaking changes без предупреждения
// firebase_auth 4.5.0
User user = FirebaseAuth.instance.currentUser!;
// firebase_auth 4.6.0
User? user = FirebaseAuth.instance.currentUser; // Null-safety
// Все коды, которые использовали этот API, сломались
Нет миграционного гайда, просто breaking change и всё. В больших проектах это беда.
3. Плохая документация
Оффициальные примеры не работали вообще:
// Из документации Firebase
await FirebaseAuth.instance.signInWithCustomToken(token);
// На практике нужно было делать:
await Future.delayed(Duration(milliseconds: 100));
await FirebaseAuth.instance.signInWithCustomToken(token);
// Без delay - падало с непонятной ошибкой
4. Неправильное обработка ошибок
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email,
password: password,
);
} catch (e) {
// Что здесь за ошибка?
// NetworkException? BadPasswordException? UserNotFoundException?
// Не понятно по типу
print(e); // Выведет какой-то криптовалютный код ошибки
}
Лучше было бы:
catch (e) {
if (e is FirebaseAuthException) {
switch (e.code) {
case 'user-not-found':
print('User not found');
break;
case 'wrong-password':
print('Wrong password');
break;
}
}
}
5. Performance issues
Простой вызов FirebaseAuth.instance.currentUser иногда занимал 2-3 секунды. Для того, чтобы просто получить текущего пользователя!
final sw = Stopwatch()..start();
final user = FirebaseAuth.instance.currentUser;
sw.stop();
print('Took ${sw.elapsedMilliseconds}ms'); // 2000-3000ms
Это замораживало весь UI при инициализации приложения.
6. Неправильный обход State Management
// FirebaseAuth требует обновления состояния вручную
FirebaseAuth.instance.authStateChanges().listen((User? user) {
if (user == null) {
// Пользователь вышел
} else {
// Пользователь вошёл
}
});
// Но на практике:
// 1. Иногда событие не приходит
// 2. Иногда приходит с задержкой
// 3. Иногда приходит дважды
Как я с этим боролся
Решение 1: Абстракция (Repository Pattern)
// Вместо того чтобы использовать Firebase напрямую
// Создал слой абстракции
class AuthRepository {
Future<void> login(String email, String password) async {
try {
final result = await _firebaseAuth.signInWithEmailAndPassword(
email: email,
password: password,
);
return result.user;
} on FirebaseAuthException catch (e) {
// Преобразовываю в свои ошибки
throw AppAuthException(
message: _mapFirebaseErrorToMessage(e.code),
);
}
}
String _mapFirebaseErrorToMessage(String code) {
switch (code) {
case 'user-not-found':
return 'User not found';
case 'wrong-password':
return 'Wrong password';
default:
return 'Unknown error';
}
}
}
Так если Firebase API изменится — меняю только в одном месте.
Решение 2: Кэширование currentUser
class AuthRepository {
User? _cachedUser;
Future<User?> getCurrentUser() async {
if (_cachedUser != null) return _cachedUser;
_cachedUser = FirebaseAuth.instance.currentUser;
return _cachedUser;
}
Future<void> clearCache() async {
_cachedUser = null;
}
}
Избежал проблемы с дорогими вызовами.
Решение 3: Своя обработка ошибок
enum AuthErrorType {
userNotFound,
wrongPassword,
emailAlreadyInUse,
networkError,
unknown,
}
class AuthException implements Exception {
final AuthErrorType type;
final String message;
AuthException({required this.type, required this.message});
}
String getErrorMessage(AuthErrorType type) {
switch (type) {
case AuthErrorType.userNotFound:
return 'User not found';
case AuthErrorType.wrongPassword:
return 'Wrong password';
// ...
}
}
Выводы
Что я вынес из этого опыта:
- Всегда создавай абстракции вокруг сторонних библиотек, даже "официальных"
- Изолируй зависимости от третьих сторон в отдельный слой
- Читай open issues перед интеграцией популярной библиотеки
- Проверяй последние update logs — может быть, это что-то сломали
- Старайся не полагаться на одну библиотеку — всегда имей план B
- Пиши тесты для обёрток вокруг сторонних библиотек
В итоге:
Не саму firebase_auth я бы назвал плохой, а версию в определённый период её разработки. К счастью, она улучшилась. Но этот опыт научил меня писать более устойчивый код и не зависеть жёстко от внешних зависимостей.