createUser method

Future<void> createUser(
  1. RaliUser user
)

//////////// //////////// Creates a new user document in Firestore with transaction safety

Implementation

// II.C - CRUD Operations
///////////////
/// Creates a new user document in Firestore with transaction safety
Future<void> createUser(RaliUser user) async {
  try {
    // Use transaction to ensure data consistency
    await _firestore.runTransaction((transaction) async {
      final userDocRef = _firestore.collection(_collectionPath).doc(user.uid);
      final userDoc = await transaction.get(userDocRef);

      // Check if user already exists to prevent duplicates
      if (userDoc.exists) {
        // Only update lastLogin if user exists
        transaction.update(userDocRef, {
          'lastLogin': FieldValue.serverTimestamp(),
        });
      } else {
        // Create new user with server timestamp
        final userData = user.toMap();
        // Ensure timestamps are handled properly
        userData['createdAt'] = FieldValue.serverTimestamp();
        userData['lastLogin'] = FieldValue.serverTimestamp();

        transaction.set(userDocRef, userData);
      }
    });

    // Update local cache
    _userCache[user.uid] = user;

  } catch (e) {
    print('Error creating user: $e');

    // Provide more detailed error information
    if (e is FirebaseException) {
      if (e.code == 'permission-denied') {
        throw RALIException('Permission denied while creating user profile', cause: e);
      } else if (e.code == 'unavailable') {
        // Store in local cache for offline support
        _userCache[user.uid] = user;

        // Track that entire user needs to be created when back online
        _pendingChanges[user.uid] = {'__create': true, ...user.toMap()};

        throw RALIException('Network unavailable, user will be synced when online', cause: e);
      }
    }

    throw RALIException('Failed to create user profile', cause: e);
  }
}