Instalar el paquete Apple Sign In
Después de configurar Firebase Auth, lo primero que debes hacer es instalar el paquete sign_in_with_apple en su versión más reciente (6.1.3). Para hacerlo, puedes optar por:
- Desde la terminal, con el siguiente comando:
flutter pub add sign_in_with_apple
- Manualmente, agregando la siguiente línea en el archivo
pubspec.yaml
de tu proyecto:
dependencies:
sign_in_with_apple: ^6.1.1
Luego, importa el paquete en tu archivo principal de Dart:
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
Configurar Apple Sign-In en Firebase
El segundo paso es añadir Apple Sign In como método de autenticación en tu proyecto de Firebase. Para ello:
- Abre tu proyecto en Firebase.
- En el menú lateral izquierdo, haz clic en Autenticación (ícono de dos personas).
- Haz clic en Método de autenticación y luego en Añadir proveedor.
- Selecciona el método Apple y actívalo para poder usarlo en tu aplicación Flutter.
- No necesitas ingresar información en el campo opcional (ID de servicio). Haz clic directamente en Guardar.
Con esto, el paquete está instalado y el método de Apple Sign In está activado en Firebase. Ahora, solo faltan dos pasos más.
Añadir el archivo GoogleService-Info.plist
Cuando agregues tu proyecto a Firebase, descarga el archivo GoogleService-Info.plist y colócalo en el directorio [mi_proyecto]/ios/Runner/
de tu aplicación Flutter, en Visual Studio.
Si no tienes este archivo, descárgalo desde la sección Configuración general de tu proyecto Firebase, en la pestaña de Configuración del proyecto y desplazándote hacia abajo hasta la sección Tus aplicaciones.
Añadir tu aplicación en Apple Developer
El último paso antes de poder usar el paquete Apple Sign In es añadir tu proyecto en la consola Apple Developer. Si aún no tienes una cuenta, crea una. Esta cuenta debe ser aprobada por un administrador, lo que puede tardar entre 2 y 3 días.
Una vez que tengas la cuenta, accede a la página principal de Apple Developer y ve a Account.
Agregar el Certificate Signing Request (CSR)
- En el menú principal, haz clic en Certificados y luego en el botón + para crear un nuevo Certificate Signing Request (CSR).
- Abre la aplicación Keychain Access en tu Mac (Trousseau d’accès en francés).
- En el menú superior, selecciona Keychain Access, luego Asistente de certificación y finalmente Solicitar un certificado a una autoridad certificadora.
- Ingresa tu correo electrónico, selecciona Guardar en disco, y guarda el archivo en el directorio de tu aplicación.
Regresa a Apple Developer y sube el archivo que acabas de crear. Luego, haz clic en Continuar y Descargar. Tu certificado ahora está añadido a Apple Developer, lo que te permite firmar tus propias solicitudes de firma.
Agregar un identificador
- Regresa al menú de Account y haz clic en Identificador, luego en +.
- Selecciona App IDs, haz clic en Continue y luego en App.
- Ingresa una breve descripción de tu aplicación y su Bundle ID.
- Este se encuentra en el archivo
google-services.json
de tu aplicación, en la líneapackage_name
.
- Este se encuentra en el archivo
- En las opciones de servicios de Apple, selecciona Push Notifications y Sign in with Apple.
- Haz clic en Continue y luego en Registrar.
Añadir la aplicación en Apple Connect
Antes de usar la función de Apple Sign In, debes añadir tu proyecto en Apple Connect:
- Ve a Apple Connect y accede a la sección Apps.
- Haz clic en el botón + para añadir una nueva app.
- Selecciona las plataformas en las que tu app estará disponible, ingresa un nombre, idioma principal y el identificador de lote que configuraste anteriormente.
- Para el UGC, puedes repetir el nombre de tu aplicación u otro que prefieras.
Añadir servicios en Xcode
El último paso de configuración es autorizar el uso de Apple Sign In en Xcode:
- Abre la carpeta iOS de tu aplicación y ve a Runner.
- Accede a Signing & Capabilities.
- Haz clic en + Capability y añade Sign in with Apple y Push Notification.
- Asegúrate de configurar esto en los diferentes modos: default, debug, etc.
Tu aplicación ya está lista para usar el paquete Apple Sign In.
Crear el sistema de inicio de sesión
Con Flutter, Firebase y Apple Sign-In configurados, es momento de codificar las interacciones en Dart. Las acciones a gestionar son:
- Verificar que el dispositivo sea un iPhone (Apple Sign-In no funciona en Android).
- Abrir la página de inicio de sesión de Apple Sign-In.
- Obtener el estado de la conexión (éxito o fallo) y la información del usuario.
- Crear un usuario en Firebase si es la primera vez que se conecta.
- Conectar al usuario en la aplicación y redirigirlo a la página deseada.
Verificar el tipo de dispositivo
Primero, verifica si el dispositivo del usuario es un iPhone o un Mac:
ElevatedButton(
onPressed: () async {
if (Platform.isIOS || Platform.isMacOS) {
// Lanzar el método de inicio de sesión
} else {
// Mostrar un mensaje de error
}
},
child: Text("Botón Apple"),
)
En esta función, se verifica si el dispositivo es un iPhone o un Mac, ya que Apple Sign-In solo está disponible para estos dispositivos. Si lo es, se inicia el proceso de inicio de sesión; de lo contrario, se muestra un mensaje de error al usuario.
Abrir la página de inicio de sesión de Apple Sign-In y recuperar información
El siguiente paso es abrir la página de inicio de sesión de Apple Sign In, permitir que el usuario inicie sesión para recuperar su información y luego reutilizarla para conectarlo con Firebase.
Para ello, comenzaremos creando una clase que contendrá las tres funciones que necesitamos:
- Verificar la plataforma en la que el usuario intenta iniciar sesión;
- Conectarlo utilizando sus credenciales de Apple Sign In;
- Verificar si el usuario es nuevo, para redirigirlo a una página diferente o crear su documento en Firebase Firestore.
Una vez creada la clase, podemos codificar nuestra función de tipo Future<String>
, que abrirá el portal de Apple Sign In y devolverá el estado del intento de inicio de sesión (autorizado, rechazado o error). Si el intento tiene éxito, recuperamos la información del usuario y la reutilizamos para conectarlo con Firebase Auth.
Aquí está el código completo:
import 'package:translate/main.dart';
import 'dart:io';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
class AppleAuthService {
// Función para verificar que la plataforma utilizada sea un iPhone
Future<void> checkPlatform() async {
if (Platform.isIOS || Platform.isMacOS) {
// Lanza el método de inicio de sesión
appleSign();
} else {
Fluttertoast.showToast(
msg: "Esta funcionalidad solo está disponible en iPhone");
}
}
// Función para conectar al usuario con Apple Sign In
Future<String> appleSign() async {
try {
// Recuperar la información de identidad del usuario mediante Apple
final appleCredential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
);
// Crear credenciales para Firebase
final oAuthCredential = OAuthProvider("apple.com").credential(
idToken: appleCredential.identityToken,
accessToken: appleCredential.authorizationCode,
);
// Conexión a Firebase
final userCredential =
await FirebaseAuth.instance.signInWithCredential(oAuthCredential);
// Verificar si el usuario es nuevo
if (userCredential.additionalUserInfo!.isNewUser) {
final user = userCredential.user!;
// await addAppleUser(user.uid, user.email ?? "");
}
return "Conexión autorizada con Apple";
} on SignInWithAppleAuthorizationException catch (e) {
if (e.code == AuthorizationErrorCode.canceled) {
return "Conexión cancelada por el usuario.";
} else {
return "Error durante la conexión: ${e.message}";
}
} catch (e) {
return "Se produjo un error inesperado: $e";
}
}
}
Para llamar a tu función, simplemente llama a la clase y especifica la función que necesitas usar. Aquí, llamaré a checkPlatform()
, que integrará las otras funciones necesarias para conectar al usuario:
ElevatedButton(
onPressed: () => AppleAuthService().checkPlatform(),
child: Text("Connexion avec Apple")
)
Explicación línea por línea
Dado que esta función utiliza varios widgets, aquí está la explicación de la utilidad de cada uno.
Future<String> appleSign() async {}
Nuestra función appleSign()
es asincrónica y devuelve un Future<String>
. Gestiona la conexión mediante Apple Sign In y devuelve un mensaje en forma de cadena que indica el resultado del intento de inicio de sesión.
1. Recuperación de la información de identidad del usuario mediante Apple
final appleCredential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
);
- Este bloque inicia el proceso de inicio de sesión con Apple.
- Utiliza el método
getAppleIDCredential
de la bibliotecaSignInWithApple
para iniciar la autenticación. Scopes
: Definen la información solicitada de la cuenta Apple del usuario:AppleIDAuthorizationScopes.email
: Recupera el correo electrónico del usuario.AppleIDAuthorizationScopes.fullName
: Recupera el nombre completo del usuario.
- El resultado (
appleCredential
) contiene información como el token de identidad (identityToken
) y el código de autorización (authorizationCode
), necesarios para la autenticación con Firebase.
2. Creación de credenciales para Firebase
final oAuthCredential = OAuthProvider("apple.com").credential(
idToken: appleCredential.identityToken,
accessToken: appleCredential.authorizationCode,
);
- Esta función crea un objeto de autenticación Firebase (
OAuthCredential
) específico para el proveedor Apple ("apple.com"
). - Utiliza la información de
appleCredential
:authorizationCode
: Código que autoriza a Firebase a acceder a la información del usuario.identityToken
: Token JWT emitido por Apple, que verifica la identidad del usuario.
- Conexión a Firebase
final userCredential =
await FirebaseAuth.instance.signInWithCredential(oAuthCredential);
- Envía las credenciales (
oAuthCredential
) a Firebase para conectar al usuario. - El resultado (
userCredential
) contiene información sobre el usuario y la conexión:userCredential.user
: Detalles del usuario conectadouserCredential.additionalUserInfo
: Información adicional, por ejemplo, si es un usuario nuevo.
4. Verificar si el usuario es nuevo
Esta parte simplemente verifica si el usuario es nuevo (isNewUser) para realizar acciones específicas.
if (userCredential.additionalUserInfo!.isNewUser) {
final user = userCredential.user!;
// Añade tu lógica si el usuario es nuevo
// Por ejemplo, guardar su información en Firestore
}
5. Devolución en caso de éxito o error
return "Conexión autorizada con Apple";
} on SignInWithAppleAuthorizationException catch (e) {
if (e.code == AuthorizationErrorCode.canceled) {
return "Conexión cancelada por el usuario.";
} else {
return "Error durante la conexión: ${e.message}";
}
} catch (e) {
return "Se produjo un error inesperado: $e";
}
Agregar un nuevo usuario a mi base de datos de Firebase
Para finalizar, una primera conexión a menudo requiere acciones específicas, como recuperar la información del usuario o permitirle configurar sus ajustes. Dado que puedes saber si se conecta por primera vez, simplemente agrega tu lógica. Por ejemplo, aquí crearé una función addAppleUser
para guardar el correo electrónico del usuario en Firebase Firestore:
// Función para conectar al usuario con Apple Sign In
// ...
if (userCredential.additionalUserInfo!.isNewUser) {
final user = userCredential.user!;
await addAppleUser(user.uid, user.email ?? "");
}
// ...
Future<void> addAppleUser(String userID, String email) {
return FirebaseFirestore.instance
.collection('Users')
.doc(userID)
.set({
'email': email,
})
.then((value) => print('Usuario agregado'))
.catchError((error) => print('Error: $error'));
}
El primer bloque verifica si el usuario se conecta por primera vez (isNewUser
). Si es así, la función recupera su ID único de Firebase (uid
) y su correo electrónico, llamando a addAppleUser()
para almacenar esta información en la base de datos Firebase de la aplicación.
Conclusión
Agregar usuarios a tu aplicación es muy importante, pero poder eliminarlos también lo es. Te explico cómo hacerlo en mi próxima guía: