← Назад к вопросам

Назови худшую библиотеку с которой сталкивался

1.3 Junior🔥 71 комментариев
#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Худшая библиотека из которых я сталкивался

Если честно, то это была версия 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';
    // ...
  }
}

Выводы

Что я вынес из этого опыта:

  1. Всегда создавай абстракции вокруг сторонних библиотек, даже "официальных"
  2. Изолируй зависимости от третьих сторон в отдельный слой
  3. Читай open issues перед интеграцией популярной библиотеки
  4. Проверяй последние update logs — может быть, это что-то сломали
  5. Старайся не полагаться на одну библиотеку — всегда имей план B
  6. Пиши тесты для обёрток вокруг сторонних библиотек

В итоге:

Не саму firebase_auth я бы назвал плохой, а версию в определённый период её разработки. К счастью, она улучшилась. Но этот опыт научил меня писать более устойчивый код и не зависеть жёстко от внешних зависимостей.