saveProviderUser static method

Future<Map<String, dynamic>> saveProviderUser({
  1. required Map<String, dynamic> providerUserData,
  2. Map<String, dynamic>? additionalData,
})

Save provider user to database (optional) - returns saved user data

Implementation

static Future<Map<String, dynamic>> saveProviderUser({
  required Map<String, dynamic> providerUserData,
  Map<String, dynamic>? additionalData,
}) async {
  final table = config.table;
  final provider = providerUserData['provider'];
  final providerId = providerUserData['providerId'];
  final email = providerUserData['email'];
  final name = providerUserData['name'];

  // Check if user exists by provider
  var user = await QueryBuilder(table: table)
      .where(config.providerColumn ?? "provider", '=', provider)
      .where(config.providerIdColumn ?? "provider_id", '=', providerId)
      .first();

  if (user != null) {
    // Build safe update data
    final updateData = <String, dynamic>{};

    // Only update email if the column exists
    final emailColumnExists = await _columnExists(table, config.emailColumn);
    if (emailColumnExists) {
      updateData[config.emailColumn] = email;
    }

    // Only update name if the column exists and name is provided
    if (name != null && config.nameColumn != null) {
      final nameColumnExists = await _columnExists(table, config.nameColumn!);
      if (nameColumnExists) {
        updateData[config.nameColumn!] = name;
      }
    }

    // Only update updated_at if the column exists
    final updatedAtExists = await _columnExists(table, 'updated_at');
    if (updatedAtExists) {
      updateData['updated_at'] = DateTime.now().toIso8601String();
    }

    if (updateData.isNotEmpty) {
      await QueryBuilder(table: table)
          .where('id', '=', user['id'])
          .update(updateData);
    }
  } else {
    // Check by email
    user = await QueryBuilder(table: table)
        .where(config.emailColumn, '=', email)
        .first();

    if (user != null) {
      // Update existing user with provider info
      final updateData = <String, dynamic>{};

      // Only update provider columns if they exist
      if (config.providerColumn != null) {
        final providerColumnExists =
            await _columnExists(table, config.providerColumn!);
        if (providerColumnExists) {
          updateData[config.providerColumn!] = provider;
        }
      }

      if (config.providerIdColumn != null) {
        final providerIdColumnExists =
            await _columnExists(table, config.providerIdColumn!);
        if (providerIdColumnExists) {
          updateData[config.providerIdColumn!] = providerId;
        }
      }

      // Only update updated_at if the column exists
      final updatedAtExists = await _columnExists(table, 'updated_at');
      if (updatedAtExists) {
        updateData['updated_at'] = DateTime.now().toIso8601String();
      }

      if (updateData.isNotEmpty) {
        await QueryBuilder(table: table)
            .where('id', '=', user['id'])
            .update(updateData);
      }
    } else {
      // Create new user with safe data
      final data = await _buildSafeUserData(
        email: email,
        hashedPassword: '', // No password for provider users
        name: name,
        additionalData: {
          if (config.providerColumn != null) config.providerColumn!: provider,
          if (config.providerIdColumn != null)
            config.providerIdColumn!: providerId,
          ...?additionalData,
        },
      );

      await QueryBuilder(table: table).insert(data);

      user = await QueryBuilder(table: table)
          .where(config.emailColumn, '=', email)
          .first();
    }
  }

  return _sanitizeUserData(user!);
}