From 6d4e37c49f2a213068767a6160efbad71ca30c68 Mon Sep 17 00:00:00 2001 From: Ademola Fadumo Date: Tue, 4 Nov 2025 22:43:11 +0100 Subject: [PATCH 1/7] feat: add spanish translations and optional logo param config --- .../Sources/Views/SignInWithAppleButton.swift | 2 +- .../Sources/Services/AuthConfiguration.swift | 28 +- .../Sources/Strings/Localizable.xcstrings | 1864 +++++++++++++++-- .../Sources/Utils/StringUtils.swift | 515 +++++ .../Sources/Views/AuthPickerView.swift | 32 +- .../Sources/Views/EmailAuthView.swift | 57 +- .../Sources/Views/EmailLinkView.swift | 2 +- .../Sources/Views/EnterPhoneNumberView.swift | 2 +- .../Views/EnterVerificationCodeView.swift | 4 +- .../Sources/Views/MFAEnrolmentView.swift | 18 +- .../Sources/Views/PasswordRecoveryView.swift | 2 +- .../Sources/Views/UpdatePasswordView.swift | 4 +- .../Sources/Components/AuthTextField.swift | 14 +- .../Views/SignInWithGoogleButton.swift | 2 +- .../Sources/Views/GenericOAuthButton.swift | 2 +- .../Sources/Views/PhoneAuthButtonView.swift | 2 +- .../Views/SignInWithTwitterButton.swift | 2 +- .../project.pbxproj | 6 +- .../App/ContentView.swift | 1 + .../FirebaseSwiftUIExample/Info.plist | 5 + 20 files changed, 2363 insertions(+), 201 deletions(-) diff --git a/FirebaseSwiftUI/FirebaseAppleSwiftUI/Sources/Views/SignInWithAppleButton.swift b/FirebaseSwiftUI/FirebaseAppleSwiftUI/Sources/Views/SignInWithAppleButton.swift index d3c5c2151a..95a51f6e27 100644 --- a/FirebaseSwiftUI/FirebaseAppleSwiftUI/Sources/Views/SignInWithAppleButton.swift +++ b/FirebaseSwiftUI/FirebaseAppleSwiftUI/Sources/Views/SignInWithAppleButton.swift @@ -29,7 +29,7 @@ public struct SignInWithAppleButton { extension SignInWithAppleButton: View { public var body: some View { AuthProviderButton( - label: "Sign in with Apple", + label: authService.string.appleLoginButtonLabel, style: .apple, accessibilityId: "sign-in-with-apple-button" ) { diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift index d760cc743f..3dcf1208e1 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift @@ -14,8 +14,10 @@ import FirebaseAuth import Foundation +import SwiftUI public struct AuthConfiguration { + public let logo: ImageResource? public let shouldHideCancelButton: Bool public let interactiveDismissEnabled: Bool public let shouldAutoUpgradeAnonymousUsers: Bool @@ -31,17 +33,21 @@ public struct AuthConfiguration { public let allowedSecondFactors: Set public let mfaIssuer: String - public init(shouldHideCancelButton: Bool = false, - interactiveDismissEnabled: Bool = true, - shouldAutoUpgradeAnonymousUsers: Bool = false, - customStringsBundle: Bundle? = nil, - tosUrl: URL? = nil, - privacyPolicyUrl: URL? = nil, - emailLinkSignInActionCodeSettings: ActionCodeSettings? = nil, - verifyEmailActionCodeSettings: ActionCodeSettings? = nil, - mfaEnabled: Bool = false, - allowedSecondFactors: Set = [.sms, .totp], - mfaIssuer: String = "Firebase Auth") { + public init( + logo: ImageResource? = nil, + shouldHideCancelButton: Bool = false, + interactiveDismissEnabled: Bool = true, + shouldAutoUpgradeAnonymousUsers: Bool = false, + customStringsBundle: Bundle? = nil, + tosUrl: URL? = nil, + privacyPolicyUrl: URL? = nil, + emailLinkSignInActionCodeSettings: ActionCodeSettings? = nil, + verifyEmailActionCodeSettings: ActionCodeSettings? = nil, + mfaEnabled: Bool = false, + allowedSecondFactors: Set = [.sms, .totp], + mfaIssuer: String = "Firebase Auth" + ) { + self.logo = logo self.shouldHideCancelButton = shouldHideCancelButton self.interactiveDismissEnabled = interactiveDismissEnabled self.shouldAutoUpgradeAnonymousUsers = shouldAutoUpgradeAnonymousUsers diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Strings/Localizable.xcstrings b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Strings/Localizable.xcstrings index 7d686924a6..bf5f780f06 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Strings/Localizable.xcstrings +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Strings/Localizable.xcstrings @@ -2,13 +2,52 @@ "sourceLanguage" : "en", "strings" : { "%@" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@" + } + } + } }, "••••••%@" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "••••••%@" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "••••••%@" + } + } + } }, "Account: %@" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Account: %@" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cuenta: %@" + } + } + } }, "AccountDisabledError" : { "comment" : "Error message displayed when the account is disabled. Use short/abbreviated translation for 'email' which is less than 15 chars.", @@ -19,6 +58,12 @@ "state" : "translated", "value" : "That email address is for an account that has been disabled." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esa dirección de correo es de una cuenta que ha sido deshabilitada." + } } } }, @@ -31,14 +76,46 @@ "state" : "translated", "value" : "This action can't be undone" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esta acción no se puede deshacer" + } } } }, "Add an extra layer of security to your account" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Add an extra layer of security to your account" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Agrega una capa adicional de seguridad a tu cuenta" + } + } + } }, "Add Another Method" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Add Another Method" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Agregar otro método" + } + } + } }, "AddPasswordAlertMessage" : { "comment" : "Alert message shown when adding account password.", @@ -49,6 +126,12 @@ "state" : "translated", "value" : "To add password to your account, you will need to sign in again." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para agregar una contraseña a tu cuenta, deberás iniciar sesión nuevamente." + } } } }, @@ -61,11 +144,30 @@ "state" : "translated", "value" : "Add password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Agregar contraseña" + } } } }, "Already have an account?" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Already have an account?" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Ya tienes una cuenta?" + } + } + } }, "AS_AddPassword" : { "comment" : "Account Settings cell title Add Password.", @@ -76,6 +178,12 @@ "state" : "translated", "value" : "Add password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Agregar contraseña" + } } } }, @@ -88,6 +196,12 @@ "state" : "translated", "value" : "Change password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cambiar contraseña" + } } } }, @@ -100,6 +214,12 @@ "state" : "translated", "value" : "Delete Account" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Eliminar cuenta" + } } } }, @@ -112,6 +232,12 @@ "state" : "translated", "value" : "Email" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Correo" + } } } }, @@ -124,6 +250,12 @@ "state" : "translated", "value" : "Name" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nombre" + } } } }, @@ -136,6 +268,12 @@ "state" : "translated", "value" : "Linked Accounts" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cuentas vinculadas" + } } } }, @@ -148,6 +286,12 @@ "state" : "translated", "value" : "Profile" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Perfil" + } } } }, @@ -160,6 +304,12 @@ "state" : "translated", "value" : "Security" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Seguridad" + } } } }, @@ -172,14 +322,62 @@ "state" : "translated", "value" : "Sign Out" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cerrar sesión" + } + } + } + }, + "Authenticating..." : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Authenticating..." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Autenticando..." + } } } }, "Authentication Method" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Authentication Method" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Método de autenticación" + } + } + } }, "Authenticator App" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Authenticator App" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aplicación de autenticación" + } + } + } }, "AuthPickerTitle" : { "comment" : "Title for auth picker screen.", @@ -190,11 +388,31 @@ "state" : "translated", "value" : "Sign in with Firebase" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión con Firebase" + } } } }, "Back" : { - "comment" : "Back button title." + "comment" : "Back button title.", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Back" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Atrás" + } + } + } }, "Cancel" : { "comment" : "Cancel button title.", @@ -205,6 +423,12 @@ "state" : "translated", "value" : "Cancel" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cancelar" + } } } }, @@ -217,6 +441,12 @@ "state" : "translated", "value" : "This type of account isn't supported by this app" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Este tipo de cuenta no es compatible con esta aplicación" + } } } }, @@ -229,17 +459,62 @@ "state" : "translated", "value" : "Can't find provider for %@." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "No se puede encontrar el proveedor para %@." + } } } }, "Change number" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Change number" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cambiar número" + } + } + } }, "Choose Authentication Method" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Choose Authentication Method" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Elige el método de autenticación" + } + } + } }, "Choose verification method:" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Choose verification method:" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Elige el método de verificación:" + } + } + } }, "ChoosePassword" : { "comment" : "Placeholder for the password text field in a sign up form.", @@ -250,6 +525,12 @@ "state" : "translated", "value" : "Choose password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Elegir contraseña" + } } } }, @@ -262,113 +543,272 @@ "state" : "translated", "value" : "Close" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cerrar" + } } } }, "Complete Setup" : { - - }, - "Complete Sign-In" : { - - }, - "Complete sign-in with your second factor" : { - - }, - "ConfirmEmail" : { - "comment" : "Title of confirm email label.", - "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Confirm Email" + "value" : "Complete Setup" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completar configuración" } } } }, - "ConfirmPasswordInputLabel" : { - "comment" : "Input label for confirming password when signing up", - "extractionState" : "manual", + "Complete Sign-In" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Confirm Password" + "value" : "Complete Sign-In" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completar inicio de sesión" } } } }, - "Copied to clipboard!" : { - - }, - "Delete" : { - "comment" : "Text of Delete action button.", - "extractionState" : "manual", + "Complete sign-in with your second factor" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Delete" + "value" : "Complete sign-in with your second factor" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Completa el inicio de sesión con tu segundo factor" } } } }, - "Delete Account" : { - - }, - "Delete Account?" : { - - }, - "DeleteAccountBody" : { - "comment" : "Alert message body shown to confirm account deletion action.", + "ConfirmEmail" : { + "comment" : "Title of confirm email label.", "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "This will erase all data associated with your account, and can't be undone You will need to sign in again to complete this action" + "value" : "Confirm Email" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Confirmar correo" } } } }, - "DeleteAccountConfirmationMessage" : { - "comment" : "Explanation message shown before deleting account.", + "Confirm Password" : { + "comment" : "Field label for confirming password", "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "This will erase all data associated with your account, and can't be undone. Are you sure you want to delete your account?" + "value" : "Confirm Password" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Confirmar contraseña" } } } }, - "DeleteAccountConfirmationTitle" : { - "comment" : "Alert message title shown to confirm account deletion action.", + "ConfirmPasswordInputLabel" : { + "comment" : "Input label for confirming password when signing up", "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Delete Account?" + "value" : "Confirm Password" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Confirmar contraseña" } } } }, - "DeleteAccountControllerTitle" : { - "comment" : "Title of Controller shown before deleting account", - "extractionState" : "manual", + "Copied to clipboard!" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Delete account" + "value" : "Copied to clipboard!" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡Copiado al portapapeles!" } } } }, - "Display Name" : { - + "Delete" : { + "comment" : "Text of Delete action button.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Eliminar" + } + } + } + }, + "Delete Account" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete Account" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Eliminar cuenta" + } + } + } + }, + "Delete Account?" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete Account?" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Eliminar cuenta?" + } + } + } + }, + "DeleteAccountBody" : { + "comment" : "Alert message body shown to confirm account deletion action.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "This will erase all data associated with your account, and can't be undone You will need to sign in again to complete this action" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esto borrará todos los datos asociados con tu cuenta y no se puede deshacer. Deberás iniciar sesión nuevamente para completar esta acción" + } + } + } + }, + "DeleteAccountConfirmationMessage" : { + "comment" : "Explanation message shown before deleting account.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "This will erase all data associated with your account, and can't be undone. Are you sure you want to delete your account?" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esto borrará todos los datos asociados con tu cuenta y no se puede deshacer. ¿Estás seguro de que deseas eliminar tu cuenta?" + } + } + } + }, + "DeleteAccountConfirmationTitle" : { + "comment" : "Alert message title shown to confirm account deletion action.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete Account?" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Eliminar cuenta?" + } + } + } + }, + "DeleteAccountControllerTitle" : { + "comment" : "Title of Controller shown before deleting account", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Delete account" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Eliminar cuenta" + } + } + } + }, + "Display Name" : { + "comment" : "Field label for display name", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Display Name" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nombre para mostrar" + } + } + } }, "Don't have an account yet?" : { "localizations" : { @@ -377,6 +817,12 @@ "state" : "translated", "value" : "Don't have an account yet?" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Aún no tienes una cuenta?" + } } } }, @@ -389,6 +835,12 @@ "state" : "translated", "value" : "Edit email" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Editar correo" + } } } }, @@ -401,6 +853,12 @@ "state" : "translated", "value" : "Edit name" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Editar nombre" + } } } }, @@ -413,6 +871,12 @@ "state" : "translated", "value" : "To change password to your account, you will need to sign in again." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para cambiar la contraseña de tu cuenta, deberás iniciar sesión nuevamente." + } } } }, @@ -425,6 +889,30 @@ "state" : "translated", "value" : "Change password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cambiar contraseña" + } + } + } + }, + "Email" : { + "comment" : "Field label for email", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Email" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Correo" + } } } }, @@ -437,6 +925,84 @@ "state" : "translated", "value" : "The email address is already in use by another account." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "La dirección de correo ya está en uso por otra cuenta." + } + } + } + }, + "Enter code from app" : { + "comment" : "Prompt for entering code from authenticator app", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter code from app" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa el código de la aplicación" + } + } + } + }, + "Enter display name for this authenticator" : { + "comment" : "Prompt for entering display name for authenticator", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter display name for this authenticator" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa el nombre para mostrar de este autenticador" + } + } + } + }, + "Enter display name for this device" : { + "comment" : "Prompt for entering display name for device", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter display name for this device" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa el nombre para mostrar de este dispositivo" + } + } + } + }, + "Enter phone number" : { + "comment" : "Prompt for entering phone number", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter phone number" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa el número de teléfono" + } } } }, @@ -449,6 +1015,12 @@ "state" : "translated", "value" : "Prefer Email link sign-in?" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Prefieres iniciar sesión con enlace por correo?" + } } } }, @@ -461,6 +1033,12 @@ "state" : "translated", "value" : "Sign in with email link" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión con enlace por correo" + } } } }, @@ -473,6 +1051,12 @@ "state" : "translated", "value" : "Emails don't match" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Los correos no coinciden" + } } } }, @@ -485,26 +1069,110 @@ "state" : "translated", "value" : "A sign-in email with additional instructions was sent to %@. Check your email to complete sign-in." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Se envió un correo de inicio de sesión con instrucciones adicionales a %@. Revisa tu correo para completar el inicio de sesión." + } } } }, "Enrolled Methods" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enrolled Methods" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Métodos registrados" + } + } + } }, "Enrolled: %@" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enrolled: %@" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registrado: %@" + } + } + } }, "Enter 6-digit code" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter 6-digit code" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa el código de 6 dígitos" + } + } + } }, "Enter the 6-digit code from your authenticator app" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter the 6-digit code from your authenticator app" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa el código de 6 dígitos de tu aplicación de autenticación" + } + } + } }, "Enter Verification Code" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter Verification Code" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa el código de verificación" + } + } + } }, "Enter Your Phone Number" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enter Your Phone Number" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa tu número de teléfono" + } + } + } }, "EnterYourEmail" : { "comment" : "Title for email entry screen, email text field placeholder. Use short/abbreviated translation for 'email' which is less than 15 chars.", @@ -515,6 +1183,12 @@ "state" : "translated", "value" : "Enter your email" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa tu correo" + } } } }, @@ -527,6 +1201,12 @@ "state" : "translated", "value" : "Enter your password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa tu contraseña" + } } } }, @@ -539,6 +1219,12 @@ "state" : "translated", "value" : "Error" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Error" + } } } }, @@ -551,6 +1237,12 @@ "state" : "translated", "value" : "You already have an account" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ya tienes una cuenta" + } } } }, @@ -563,6 +1255,12 @@ "state" : "translated", "value" : "First & last name" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nombre y apellido" + } } } }, @@ -575,6 +1273,12 @@ "state" : "translated", "value" : "Send password recovery email" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviar correo de recuperación de contraseña" + } } } }, @@ -587,11 +1291,30 @@ "state" : "translated", "value" : "Trouble signing in?" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Problemas para iniciar sesión?" + } } } }, "Get Started" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Get Started" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Comenzar" + } + } + } }, "InvalidEmailError" : { "comment" : "Error message displayed when user enters an invalid email address. Use short/abbreviated translation for 'email' which is less than 15 chars.", @@ -602,6 +1325,30 @@ "state" : "translated", "value" : "That email address isn't correct." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esa dirección de correo no es correcta." + } + } + } + }, + "Invalid OAuth Provider" : { + "comment" : "Error message displayed when OAuth provider configuration is invalid.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Invalid OAuth Provider" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Proveedor OAuth inválido" + } } } }, @@ -614,6 +1361,12 @@ "state" : "translated", "value" : "Password cannot be empty." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "La contraseña no puede estar vacía." + } } } }, @@ -624,23 +1377,94 @@ "state" : "translated", "value" : "Login" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión" + } } } }, "Manage Two-Factor Authentication" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Manage Two-Factor Authentication" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Administrar autenticación de dos factores" + } + } + } }, "Manage your authentication methods" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Manage your authentication methods" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Administra tus métodos de autenticación" + } + } + } }, "Manual Entry Key:" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Manual Entry Key:" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Clave de entrada manual:" + } + } + } }, "MFA is not enabled in the current configuration. Please contact your administrator." : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "MFA is not enabled in the current configuration. Please contact your administrator." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "MFA no está habilitado en la configuración actual. Por favor, contacta a tu administrador." + } + } + } }, "Multi-Factor Authentication Disabled" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Multi-Factor Authentication Disabled" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Autenticación multifactor deshabilitada" + } + } + } }, "Name" : { "comment" : "Label next to a name text field.", @@ -651,38 +1475,113 @@ "state" : "translated", "value" : "Name" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nombre" + } + } + } + }, + "Next" : { + "comment" : "Next button title.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Next" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Siguiente" + } + } + } + }, + "No Authentication Methods" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No Authentication Methods" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sin métodos de autenticación" + } + } + } + }, + "No Authentication Methods Available" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No Authentication Methods Available" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "No hay métodos de autenticación disponibles" + } + } + } + }, + "No MFA methods are configured as allowed. Please contact your administrator." : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "No MFA methods are configured as allowed. Please contact your administrator." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "No hay métodos MFA configurados como permitidos. Por favor, contacta a tu administrador." + } } } }, - "Next" : { - "comment" : "Next button title.", + "OK" : { + "comment" : "OK button title.", "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Next" + "value" : "OK" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aceptar" } } } }, - "No Authentication Methods" : { - - }, - "No Authentication Methods Available" : { - - }, - "No MFA methods are configured as allowed. Please contact your administrator." : { - - }, - "OK" : { - "comment" : "OK button title.", + "Password" : { + "comment" : "Field label for password", "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "OK" + "value" : "Password" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Contraseña" } } } @@ -696,6 +1595,12 @@ "state" : "translated", "value" : "Follow the instructions sent to %@ to recover your password." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sigue las instrucciones enviadas a %@ para recuperar tu contraseña." + } } } }, @@ -708,6 +1613,12 @@ "state" : "translated", "value" : "Check your email" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Revisa tu correo" + } } } }, @@ -720,6 +1631,12 @@ "state" : "translated", "value" : "Get instructions sent to this email that explain how to reset your password." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Recibe instrucciones enviadas a este correo que explican cómo restablecer tu contraseña." + } } } }, @@ -732,6 +1649,12 @@ "state" : "translated", "value" : "Recover password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Recuperar contraseña" + } } } }, @@ -742,13 +1665,52 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "You’ve already used %@ to sign in. Enter your password for that account." + "value" : "You've already used %@ to sign in. Enter your password for that account." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ya has usado %@ para iniciar sesión. Ingresa tu contraseña para esa cuenta." + } + } + } + }, + "Phone" : { + "comment" : "Field label for phone", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Phone" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Teléfono" } } } }, "Phone Number" : { - + "comment" : "Field label for phone number", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Phone Number" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Número de teléfono" + } + } + } }, "PlaceholderChosePassword" : { "comment" : "Placeholder of secret input cell when user changes password.", @@ -759,6 +1721,12 @@ "state" : "translated", "value" : "Choose password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Elegir contraseña" + } } } }, @@ -771,6 +1739,12 @@ "state" : "translated", "value" : "Enter your email" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa tu correo" + } } } }, @@ -783,6 +1757,12 @@ "state" : "translated", "value" : "Enter your name" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa tu nombre" + } } } }, @@ -795,6 +1775,12 @@ "state" : "translated", "value" : "Enter your password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ingresa tu contraseña" + } } } }, @@ -807,6 +1793,12 @@ "state" : "translated", "value" : "New password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nueva contraseña" + } } } }, @@ -819,6 +1811,12 @@ "state" : "translated", "value" : "Privacy Policy" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Política de privacidad" + } } } }, @@ -831,6 +1829,12 @@ "state" : "translated", "value" : "Facebook" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Facebook" + } } } }, @@ -843,6 +1847,12 @@ "state" : "translated", "value" : "Google" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Google" + } } } }, @@ -855,6 +1865,12 @@ "state" : "translated", "value" : "Email" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Correo" + } } } }, @@ -867,6 +1883,12 @@ "state" : "translated", "value" : "Twitter" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Twitter" + } } } }, @@ -877,7 +1899,13 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "You’ve already used %@. Sign in with %@ to continue." + "value" : "You've already used %@. Sign in with %@ to continue." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ya has usado %@. Inicia sesión con %@ para continuar." } } } @@ -891,11 +1919,30 @@ "state" : "translated", "value" : "In order to change your password, you first need to enter your current password." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para cambiar tu contraseña, primero debes ingresar tu contraseña actual." + } } } }, "Remove" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Remove" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Eliminar" + } + } + } }, "Resend" : { "comment" : "Resend button title.", @@ -906,11 +1953,30 @@ "state" : "translated", "value" : "Resend" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Reenviar" + } } } }, "Resend Code" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Resend Code" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Reenviar código" + } + } + } }, "Save" : { "comment" : "Save button title.", @@ -921,14 +1987,46 @@ "state" : "translated", "value" : "Save" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Guardar" + } } } }, "Scan QR Code" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scan QR Code" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Escanear código QR" + } + } + } }, "Scan with your authenticator app or tap to open directly" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Scan with your authenticator app or tap to open directly" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Escanea con tu aplicación de autenticación o toca para abrir directamente" + } + } + } }, "Send" : { "comment" : "Send button title.", @@ -939,11 +2037,30 @@ "state" : "translated", "value" : "Send" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviar" + } } } }, "Send Code" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Send Code" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviar código" + } + } + } }, "SendEmailSignInLinkButtonLabel" : { "comment" : "Button label for sending email sign-in link", @@ -954,62 +2071,221 @@ "state" : "translated", "value" : "Send email sign-in link" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviar enlace de inicio de sesión por correo" + } } } }, "Set Up Two-Factor Authentication" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Set Up Two-Factor Authentication" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configurar autenticación de dos factores" + } + } + } }, "Set up two-factor authentication to add an extra layer of security to your account." : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Set up two-factor authentication to add an extra layer of security to your account." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Configura la autenticación de dos factores para agregar una capa adicional de seguridad a tu cuenta." + } + } + } }, "Sign up" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sign up" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Registrarse" + } + } + } + }, + "SignedIn" : { + "comment" : "Title of successfully signed in label.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Signed in!" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¡Sesión iniciada!" + } + } + } + }, + "SignInEmailSent" : { + "comment" : "Message displayed after the email of sign-in link is sent.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sign-in email Sent" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Correo de inicio de sesión enviado" + } + } + } + }, + "SignInTitle" : { + "comment" : "Title for sign in screen and sign in button.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sign in" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión" + } + } + } + }, + "SignInTooManyTimesError" : { + "comment" : "Error message displayed after user trying to sign in too many times.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "You've entered an incorrect password too many times. Try again in a few minutes." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Has ingresado una contraseña incorrecta demasiadas veces. Intenta nuevamente en unos minutos." + } + } + } + }, + "Sign in with Apple" : { + "comment" : "Sign in with Apple button label.", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sign in with Apple" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión con Apple" + } + } + } }, - "SignedIn" : { - "comment" : "Title of successfully signed in label.", + "Sign in with Facebook" : { + "comment" : "Sign in with Facebook button label.", "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Signed in!" + "value" : "Sign in with Facebook" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión con Facebook" } } } }, - "SignInEmailSent" : { - "comment" : "Message displayed after the email of sign-in link is sent.", + "Sign in with Google" : { + "comment" : "Sign in with Google button label.", "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Sign-in email Sent" + "value" : "Sign in with Google" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión con Google" } } } }, - "SignInTitle" : { - "comment" : "Title for sign in screen and sign in button.", + "Sign in with Phone" : { + "comment" : "Sign in with Phone button label.", "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Sign in" + "value" : "Sign in with Phone" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión con teléfono" } } } }, - "SignInTooManyTimesError" : { - "comment" : "Error message displayed after user trying to sign in too many times.", + "Sign in with X" : { + "comment" : "Sign in with X (Twitter) button label.", "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "You’ve entered an incorrect password too many times. Try again in a few minutes." + "value" : "Sign in with X" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión con X" } } } @@ -1023,6 +2299,12 @@ "state" : "translated", "value" : "Sign in with email" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión con correo" + } } } }, @@ -1035,6 +2317,12 @@ "state" : "translated", "value" : "Sign in with %@" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Iniciar sesión con %@" + } } } }, @@ -1047,6 +2335,12 @@ "state" : "translated", "value" : "Create account" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crear cuenta" + } } } }, @@ -1059,20 +2353,78 @@ "state" : "translated", "value" : "Too many account requests are coming from your IP address. Try again in a few minutes." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Demasiadas solicitudes de cuenta provienen de tu dirección IP. Intenta nuevamente en unos minutos." + } } } }, "SMS Authentication" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "SMS Authentication" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Autenticación por SMS" + } + } + } }, "SMS Verification" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "SMS Verification" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Verificación por SMS" + } + } + } }, "SMS: %@" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "SMS: %@" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "SMS: %@" + } + } + } }, "Tap to open in authenticator app" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Tap to open in authenticator app" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Toca para abrir en la aplicación de autenticación" + } + } + } }, "TermsOfService" : { "comment" : "Text linked to a web page with the Terms of Service content.", @@ -1083,6 +2435,12 @@ "state" : "translated", "value" : "Terms of Service" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Términos de servicio" + } } } }, @@ -1095,11 +2453,30 @@ "state" : "translated", "value" : "By continuing, you are indicating that you accept our %@ and %@." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Al continuar, indicas que aceptas nuestros %@ y %@." + } } } }, "This action cannot be undone. All your data will be permanently deleted. You may need to reauthenticate to complete this action." : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "This action cannot be undone. All your data will be permanently deleted. You may need to reauthenticate to complete this action." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esta acción no se puede deshacer. Todos tus datos se eliminarán permanentemente. Es posible que debas volver a autenticarte para completar esta acción." + } + } + } }, "TroubleGettingEmailMessage" : { "comment" : "Alert message displayed when user having trouble getting email.", @@ -1110,6 +2487,12 @@ "state" : "translated", "value" : "Try these common fixes: \n - Check if the email was marked as spam or filtered.\n - Check your internet connection.\n - Check that you did not misspell your email.\n - Check that your inbox space is not running out or other inbox settings related issues.\n If the steps above didn't work, you can resend the email. Note that this will deactivate the link in the older email." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Prueba estas soluciones comunes: \n - Verifica si el correo fue marcado como spam o filtrado.\n - Verifica tu conexión a internet.\n - Verifica que no hayas escrito mal tu correo.\n - Verifica que tu bandeja de entrada no esté llena u otros problemas relacionados con la configuración de la bandeja de entrada.\n Si los pasos anteriores no funcionaron, puedes reenviar el correo. Ten en cuenta que esto desactivará el enlace del correo anterior." + } } } }, @@ -1122,14 +2505,46 @@ "state" : "translated", "value" : "Trouble getting emails?" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Problemas para recibir correos?" + } } } }, "Two-Factor Authentication" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Two-Factor Authentication" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Autenticación de dos factores" + } + } + } }, "Unable to generate QR Code" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unable to generate QR Code" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "No se puede generar el código QR" + } + } + } }, "UnlinkAction" : { "comment" : "Button title for unlinking account action.", @@ -1140,6 +2555,12 @@ "state" : "translated", "value" : "Unlink" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Desvincular" + } } } }, @@ -1152,6 +2573,12 @@ "state" : "translated", "value" : "Unlink account" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Desvincular cuenta" + } } } }, @@ -1164,6 +2591,12 @@ "state" : "translated", "value" : "You will no longer be able to sign in using your account" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ya no podrás iniciar sesión usando tu cuenta" + } } } }, @@ -1176,6 +2609,12 @@ "state" : "translated", "value" : "Unlink account?" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Desvincular cuenta?" + } } } }, @@ -1188,6 +2627,12 @@ "state" : "translated", "value" : "Linked account" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Cuenta vinculada" + } } } }, @@ -1199,6 +2644,12 @@ "state" : "translated", "value" : "Update password" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Actualizar contraseña" + } } } }, @@ -1211,6 +2662,12 @@ "state" : "translated", "value" : "To change email address associated with your account, you will need to sign in again." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para cambiar la dirección de correo asociada con tu cuenta, deberás iniciar sesión nuevamente." + } } } }, @@ -1223,11 +2680,30 @@ "state" : "translated", "value" : "In order to change your password, you first need to enter your current password." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Para cambiar tu contraseña, primero debes ingresar tu contraseña actual." + } } } }, "Use an authenticator app like Google Authenticator or Authy to generate verification codes." : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Use an authenticator app like Google Authenticator or Authy to generate verification codes." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Usa una aplicación de autenticación como Google Authenticator o Authy para generar códigos de verificación." + } + } + } }, "UserNotFoundError" : { "comment" : "Error message displayed when there's no account matching the email address. Use short/abbreviated translation for 'email' which is less than 15 chars.", @@ -1236,13 +2712,70 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "That email address doesn’t match an existing account." + "value" : "That email address doesn't match an existing account." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Esa dirección de correo no coincide con una cuenta existente." + } + } + } + }, + "Send a password recovery link to your email" : { + "comment" : "Field label for password recovery email", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Send a password recovery link to your email" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviar un enlace de recuperación de contraseña a tu correo" + } + } + } + }, + "Send a sign-in link to your email" : { + "comment" : "Field label for sign-in email link", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Send a sign-in link to your email" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviar un enlace de inicio de sesión a tu correo" } } } }, "Verification Code" : { - + "comment" : "Field label for verification code", + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Verification Code" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Código de verificación" + } + } + } }, "Verify email address?" : { "comment" : "Label for sending email verification to user.", @@ -1252,6 +2785,12 @@ "state" : "translated", "value" : "Verify email address?" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "¿Verificar dirección de correo?" + } } } }, @@ -1264,23 +2803,94 @@ "state" : "translated", "value" : "Verify it's you" } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Verifica que eres tú" + } } } }, "We sent a code to %@" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "We sent a code to %@" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviamos un código a %@" + } + } + } }, "We'll send a code to ••••••%@" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "We'll send a code to ••••••%@" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviaremos un código a ••••••%@" + } + } + } }, "We'll send a verification code to this number" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "We'll send a verification code to this number" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviaremos un código de verificación a este número" + } + } + } }, "We'll send a verification code to your phone" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "We'll send a verification code to your phone" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviaremos un código de verificación a tu teléfono" + } + } + } }, "We'll send a verification code to your phone number each time you sign in." : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "We'll send a verification code to your phone number each time you sign in." + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enviaremos un código de verificación a tu número de teléfono cada vez que inicies sesión." + } + } + } }, "WeakPasswordError" : { "comment" : "Error message displayed when the password is too weak.", @@ -1291,6 +2901,12 @@ "state" : "translated", "value" : "Password must be at least 6 characters long." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "La contraseña debe tener al menos 6 caracteres." + } } } }, @@ -1303,6 +2919,12 @@ "state" : "translated", "value" : "The email and password you entered don't match." } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "El correo y la contraseña que ingresaste no coinciden." + } } } } diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift index 8b26f1f34c..affdbb002d 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift @@ -281,6 +281,34 @@ public class StringUtils { return localizedString(for: "Already have an account?") } + /// Google provider + /// found in: + /// - SignInWithGoogleButton + public var googleLoginButtonLabel: String { + return localizedString(for: "Sign in with Google") + } + + /// Apple provider + /// found in: + /// - SignInWithAppleButton + public var appleLoginButtonLabel: String { + return localizedString(for: "Sign in with Apple") + } + + /// Twitter/X provider + /// found in: + /// - SignInWithTwitterButton + public var twitterLoginButtonLabel: String { + return localizedString(for: "Sign in with X") + } + + /// Phone provider + /// found in: + /// - PhoneAuthButtonView + public var phoneLoginButtonLabel: String { + return localizedString(for: "Sign in with Phone") + } + /// Facebook provider /// found in: /// - SignInWithFacebookButton @@ -420,4 +448,491 @@ public class StringUtils { public var alertErrorTitle: String { return localizedString(for: "Error") } + + /// Authenticating overlay message + /// found in: + /// - AuthPickerView + public var authenticatingMessage: String { + return localizedString(for: "Authenticating...") + } + + /// Two-Factor Authentication + /// found in: + /// - MFAEnrolmentView + /// - MFAManagementView + public var twoFactorAuthenticationLabel: String { + return localizedString(for: "Two-Factor Authentication") + } + + /// Set Up Two-Factor Authentication + /// found in: + /// - MFAEnrolmentView + public var setUpTwoFactorAuthenticationLabel: String { + return localizedString(for: "Set Up Two-Factor Authentication") + } + + /// Manage Two-Factor Authentication + /// found in: + /// - MFAManagementView + public var manageTwoFactorAuthenticationLabel: String { + return localizedString(for: "Manage Two-Factor Authentication") + } + + /// Complete Sign-In + /// found in: + /// - MFAResolutionView + public var completeSignInLabel: String { + return localizedString(for: "Complete Sign-In") + } + + /// Complete Setup + /// found in: + /// - MFAEnrolmentView + public var completeSetupLabel: String { + return localizedString(for: "Complete Setup") + } + + /// Choose Authentication Method + /// found in: + /// - MFAEnrolmentView + /// - MFAResolutionView + public var chooseAuthenticationMethodLabel: String { + return localizedString(for: "Choose Authentication Method") + } + + /// SMS Authentication + /// found in: + /// - MFAEnrolmentView + /// - MFAResolutionView + public var smsAuthenticationLabel: String { + return localizedString(for: "SMS Authentication") + } + + /// Authenticator App + /// found in: + /// - MFAEnrolmentView + /// - MFAResolutionView + public var authenticatorAppLabel: String { + return localizedString(for: "Authenticator App") + } + + /// Enter Your Phone Number + /// found in: + /// - MFAEnrolmentView + /// - EnterPhoneNumberView + public var enterYourPhoneNumberLabel: String { + return localizedString(for: "Enter Your Phone Number") + } + + /// Phone Number + /// found in: + /// - MFAEnrolmentView + /// - EnterPhoneNumberView + public var phoneNumberLabel: String { + return localizedString(for: "Phone Number") + } + + /// Send Code + /// found in: + /// - MFAEnrolmentView + /// - EnterPhoneNumberView + public var sendCodeLabel: String { + return localizedString(for: "Send Code") + } + + /// Enter Verification Code + /// found in: + /// - MFAEnrolmentView + /// - MFAResolutionView + /// - EnterVerificationCodeView + public var enterVerificationCodeLabel: String { + return localizedString(for: "Enter Verification Code") + } + + /// Verification Code + /// found in: + /// - MFAEnrolmentView + /// - MFAResolutionView + /// - EnterVerificationCodeView + public var verificationCodeLabel: String { + return localizedString(for: "Verification Code") + } + + /// Scan QR Code + /// found in: + /// - MFAEnrolmentView + public var scanQRCodeLabel: String { + return localizedString(for: "Scan QR Code") + } + + /// Manual Entry Key: + /// found in: + /// - MFAEnrolmentView + public var manualEntryKeyLabel: String { + return localizedString(for: "Manual Entry Key:") + } + + /// Enter 6-digit code + /// found in: + /// - MFAEnrolmentView + public var enterSixDigitCodeLabel: String { + return localizedString(for: "Enter 6-digit code") + } + + /// Scan with your authenticator app or tap to open directly + /// found in: + /// - MFAEnrolmentView + public var scanWithAuthenticatorAppMessage: String { + return localizedString(for: "Scan with your authenticator app or tap to open directly") + } + + /// Tap to open in authenticator app + /// found in: + /// - MFAEnrolmentView + public var tapToOpenInAuthenticatorAppLabel: String { + return localizedString(for: "Tap to open in authenticator app") + } + + /// Use an authenticator app like Google Authenticator or Authy to generate verification codes. + /// found in: + /// - MFAEnrolmentView + public var authenticatorAppInstructionsMessage: String { + return localizedString(for: "Use an authenticator app like Google Authenticator or Authy to generate verification codes.") + } + + /// Set up two-factor authentication to add an extra layer of security to your account. + /// found in: + /// - MFAEnrolmentView + public var setUpTwoFactorAuthMessage: String { + return localizedString(for: "Set up two-factor authentication to add an extra layer of security to your account.") + } + + /// We'll send a verification code to this number + /// found in: + /// - MFAEnrolmentView + public var sendVerificationCodeToNumberMessage: String { + return localizedString(for: "We'll send a verification code to this number") + } + + /// We'll send a verification code to your phone + /// found in: + /// - MFAEnrolmentView + public var sendVerificationCodeToPhoneMessage: String { + return localizedString(for: "We'll send a verification code to your phone") + } + + /// We'll send a verification code to your phone number each time you sign in. + /// found in: + /// - MFAEnrolmentView + public var sendVerificationCodeEachSignInMessage: String { + return localizedString(for: "We'll send a verification code to your phone number each time you sign in.") + } + + /// Unable to generate QR Code + /// found in: + /// - MFAEnrolmentView + public var unableToGenerateQRCodeMessage: String { + return localizedString(for: "Unable to generate QR Code") + } + + /// Copied to clipboard! + /// found in: + /// - MFAEnrolmentView + public var copiedToClipboardMessage: String { + return localizedString(for: "Copied to clipboard!") + } + + /// Multi-Factor Authentication Disabled + /// found in: + /// - MFAEnrolmentView + /// - MFAResolutionView + public var mfaDisabledLabel: String { + return localizedString(for: "Multi-Factor Authentication Disabled") + } + + /// MFA is not enabled in the current configuration. Please contact your administrator. + /// found in: + /// - MFAEnrolmentView + /// - MFAResolutionView + public var mfaNotEnabledMessage: String { + return localizedString(for: "MFA is not enabled in the current configuration. Please contact your administrator.") + } + + /// No Authentication Methods Available + /// found in: + /// - MFAEnrolmentView + /// - MFAResolutionView + public var noAuthenticationMethodsAvailableLabel: String { + return localizedString(for: "No Authentication Methods Available") + } + + /// No MFA methods are configured as allowed. Please contact your administrator. + /// found in: + /// - MFAEnrolmentView + /// - MFAResolutionView + public var noMFAMethodsConfiguredMessage: String { + return localizedString(for: "No MFA methods are configured as allowed. Please contact your administrator.") + } + + /// Complete sign-in with your second factor + /// found in: + /// - MFAResolutionView + public var completeSignInWithSecondFactorMessage: String { + return localizedString(for: "Complete sign-in with your second factor") + } + + /// Choose verification method: + /// found in: + /// - MFAResolutionView + public var chooseVerificationMethodLabel: String { + return localizedString(for: "Choose verification method:") + } + + /// SMS Verification + /// found in: + /// - MFAResolutionView + public var smsVerificationLabel: String { + return localizedString(for: "SMS Verification") + } + + /// We sent a code to %@ + /// found in: + /// - MFAResolutionView + public var sentCodeToNumberMessage: String { + return localizedString(for: "We sent a code to %@") + } + + /// We'll send a code to ••••••%@ + /// found in: + /// - MFAResolutionView + public var sendCodeToMaskedNumberMessage: String { + return localizedString(for: "We'll send a code to ••••••%@") + } + + /// Enter the 6-digit code from your authenticator app + /// found in: + /// - MFAResolutionView + public var enterCodeFromAuthenticatorAppMessage: String { + return localizedString(for: "Enter the 6-digit code from your authenticator app") + } + + /// Resend Code + /// found in: + /// - MFAResolutionView + /// - EnterVerificationCodeView + public var resendCodeLabel: String { + return localizedString(for: "Resend Code") + } + + /// Change number + /// found in: + /// - EnterVerificationCodeView + public var changeNumberLabel: String { + return localizedString(for: "Change number") + } + + /// Manage your authentication methods + /// found in: + /// - MFAManagementView + public var manageAuthenticationMethodsMessage: String { + return localizedString(for: "Manage your authentication methods") + } + + /// Enrolled Methods + /// found in: + /// - MFAManagementView + public var enrolledMethodsLabel: String { + return localizedString(for: "Enrolled Methods") + } + + /// No Authentication Methods + /// found in: + /// - MFAManagementView + public var noAuthenticationMethodsLabel: String { + return localizedString(for: "No Authentication Methods") + } + + /// Add an extra layer of security to your account + /// found in: + /// - MFAManagementView + public var addExtraSecurityLayerMessage: String { + return localizedString(for: "Add an extra layer of security to your account") + } + + /// Add Another Method + /// found in: + /// - MFAManagementView + public var addAnotherMethodLabel: String { + return localizedString(for: "Add Another Method") + } + + /// Get Started + /// found in: + /// - MFAManagementView + public var getStartedLabel: String { + return localizedString(for: "Get Started") + } + + /// Remove + /// found in: + /// - MFAManagementView + public var removeLabel: String { + return localizedString(for: "Remove") + } + + /// Authentication Method + /// found in: + /// - MFAManagementView + public var authenticationMethodLabel: String { + return localizedString(for: "Authentication Method") + } + + /// Enrolled: %@ + /// found in: + /// - MFAManagementView + public var enrolledDateLabel: String { + return localizedString(for: "Enrolled: %@") + } + + /// SMS: %@ + /// found in: + /// - MFAManagementView + public var smsPhoneLabel: String { + return localizedString(for: "SMS: %@") + } + + /// Delete Account + /// found in: + /// - SignedInView + public var deleteAccountLabel: String { + return localizedString(for: "Delete Account") + } + + /// Delete Account? + /// found in: + /// - SignedInView + public var deleteAccountConfirmationLabel: String { + return localizedString(for: "Delete Account?") + } + + /// This action cannot be undone. All your data will be permanently deleted. You may need to reauthenticate to complete this action. + /// found in: + /// - SignedInView + public var deleteAccountWarningMessage: String { + return localizedString(for: "This action cannot be undone. All your data will be permanently deleted. You may need to reauthenticate to complete this action.") + } + + /// Invalid OAuth Provider error + /// found in: + /// - GenericOAuthButton + public var invalidOAuthProviderError: String { + return localizedString(for: "Invalid OAuth Provider") + } + + // MARK: - Field Labels + + /// Email field label + /// found in: + /// - EmailAuthView + public var emailFieldLabel: String { + return localizedString(for: "Email") + } + + /// Password field label + /// found in: + /// - EmailAuthView + public var passwordFieldLabel: String { + return localizedString(for: "Password") + } + + /// Confirm Password field label + /// found in: + /// - EmailAuthView + public var confirmPasswordFieldLabel: String { + return localizedString(for: "Confirm Password") + } + + /// Phone Number field label + /// found in: + /// - MFAEnrolmentView + public var phoneNumberFieldLabel: String { + return localizedString(for: "Phone Number") + } + + /// Display Name field label + /// found in: + /// - MFAEnrolmentView + public var displayNameFieldLabel: String { + return localizedString(for: "Display Name") + } + + /// Verification Code field label + /// found in: + /// - MFAEnrolmentView + public var verificationCodeFieldLabel: String { + return localizedString(for: "Verification Code") + } + + /// Send a password recovery link to your email field label + /// found in: + /// - PasswordRecoveryView + public var passwordRecoveryEmailFieldLabel: String { + return localizedString(for: "Send a password recovery link to your email") + } + + /// Send a sign-in link to your email field label + /// found in: + /// - EmailLinkView + public var signInLinkEmailFieldLabel: String { + return localizedString(for: "Send a sign-in link to your email") + } + + /// Enter phone number prompt + /// found in: + /// - MFAEnrolmentView + public var enterPhoneNumberPrompt: String { + return localizedString(for: "Enter phone number") + } + + /// Enter display name for this device prompt + /// found in: + /// - MFAEnrolmentView + public var enterDisplayNameForDevicePrompt: String { + return localizedString(for: "Enter display name for this device") + } + + /// Enter display name for this authenticator prompt + /// found in: + /// - MFAEnrolmentView + public var enterDisplayNameForAuthenticatorPrompt: String { + return localizedString(for: "Enter display name for this authenticator") + } + + /// Enter code from app prompt + /// found in: + /// - MFAEnrolmentView + public var enterCodeFromAppPrompt: String { + return localizedString(for: "Enter code from app") + } + + /// Phone field label + /// found in: + /// - EnterPhoneNumberView + public var phoneFieldLabel: String { + return localizedString(for: "Phone") + } + + /// We sent a code to number message + /// found in: + /// - EnterVerificationCodeView + public func sentCodeMessage(phoneNumber: String) -> String { + return String(format: localizedString(for: "We sent a code to %@"), phoneNumber) + } + + /// Change number label + /// found in: + /// - EnterVerificationCodeView + public var changeNumberButtonLabel: String { + return localizedString(for: "Change number") + } } diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift index e8266cc136..f4d70ad4a8 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift @@ -21,7 +21,7 @@ public struct AuthPickerView { public init(@ViewBuilder content: @escaping () -> Content = { EmptyView() }) { self.content = content } - + @Environment(AuthService.self) private var authService private let content: () -> Content } @@ -76,7 +76,7 @@ extension AuthPickerView: View { .interactiveDismissDisabled(authService.configuration.interactiveDismissEnabled) } } - + @ToolbarContentBuilder var toolbar: some ToolbarContent { ToolbarItem(placement: .topBarTrailing) { @@ -85,20 +85,34 @@ extension AuthPickerView: View { authService.isPresented = false } label: { Image(systemName: "xmark") + .foregroundStyle(Color(UIColor.label)) } } } } - + @ViewBuilder var authPickerViewInternal: some View { @Bindable var authService = authService VStack { - if authService.authenticationState == .unauthenticated { + if authService.authenticationState == .authenticated { + SignedInView() + } else { authMethodPicker .safeAreaPadding() - } else { - SignedInView() + } + } + .overlay { + if authService.authenticationState == .authenticating { + VStack(spacing: 24) { + ProgressView() + .scaleEffect(1.25) + .tint(.white) + Text("Authenticating...") + .foregroundStyle(.white) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(.black.opacity(0.7)) } } .errorAlert( @@ -106,13 +120,13 @@ extension AuthPickerView: View { okButtonLabel: authService.string.okButtonLabel ) } - + @ViewBuilder var authMethodPicker: some View { GeometryReader { proxy in ScrollView { VStack(spacing: 24) { - Image(Assets.firebaseAuthLogo) + Image(authService.configuration.logo ?? Assets.firebaseAuthLogo) .resizable() .aspectRatio(contentMode: .fit) .frame(width: 100, height: 100) @@ -126,7 +140,7 @@ extension AuthPickerView: View { } } } - + @ViewBuilder func otherSignInOptions(_ proxy: GeometryProxy) -> some View { VStack { diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift index 58c88e89de..3a3977e2f1 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift @@ -32,15 +32,15 @@ private enum FocusableField: Hashable { @MainActor public struct EmailAuthView { @Environment(AuthService.self) private var authService - + @State private var email = "" @State private var password = "" @State private var confirmPassword = "" - + @FocusState private var focus: FocusableField? - + public init() {} - + private var isValid: Bool { return if authService.authenticationFlow == .signIn { !email.isEmpty && !password.isEmpty @@ -48,11 +48,11 @@ public struct EmailAuthView { !email.isEmpty && !password.isEmpty && password == confirmPassword } } - + private func signInWithEmailPassword() async { try? await authService.signIn(email: email, password: password) } - + private func createUserWithEmailPassword() async { try? await authService.createUser(email: email, password: password) } @@ -63,7 +63,7 @@ extension EmailAuthView: View { VStack(spacing: 16) { AuthTextField( text: $email, - localizedTitle: "Email", + label: authService.string.emailFieldLabel, prompt: authService.string.emailInputLabel, keyboardType: .emailAddress, contentType: .emailAddress, @@ -78,7 +78,7 @@ extension EmailAuthView: View { .accessibilityIdentifier("email-field") AuthTextField( text: $password, - localizedTitle: "Password", + label: authService.string.passwordFieldLabel, prompt: authService.string.passwordInputLabel, contentType: .password, sensitive: true, @@ -101,11 +101,11 @@ extension EmailAuthView: View { } .accessibilityIdentifier("password-recovery-button") } - + if authService.authenticationFlow == .signUp { AuthTextField( text: $confirmPassword, - localizedTitle: "Confirm Password", + label: authService.string.confirmPasswordFieldLabel, prompt: authService.string.confirmPasswordInputLabel, contentType: .password, sensitive: true, @@ -120,7 +120,7 @@ extension EmailAuthView: View { .focused($focus, equals: .confirmPassword) .accessibilityIdentifier("confirm-password-field") } - + Button(action: { Task { if authService.authenticationFlow == .signIn { @@ -133,9 +133,8 @@ extension EmailAuthView: View { if authService.authenticationState != .authenticating { Text( authService.authenticationFlow == .signIn - ? authService.string - .signInWithEmailButtonLabel - : authService.string.signUpWithEmailButtonLabel + ? authService.string.signInWithEmailButtonLabel + : authService.string.signUpWithEmailButtonLabel ) .padding(.vertical, 8) .frame(maxWidth: .infinity) @@ -152,31 +151,31 @@ extension EmailAuthView: View { .buttonStyle(.borderedProminent) .accessibilityIdentifier("sign-in-button") } - HStack { - Text( + Button(action: { + withAnimation { + authService.authenticationFlow = authService - .authenticationFlow == .signIn + .authenticationFlow == .signIn ? .signUp : .signIn + } + }) { + HStack(spacing: 4) { + Text( + authService + .authenticationFlow == .signIn ? authService.string.dontHaveAnAccountYetLabel : authService.string.alreadyHaveAnAccountLabel - ) - Button(action: { - withAnimation { - authService.authenticationFlow = - authService - .authenticationFlow == .signIn ? .signUp : .signIn - } - }) { + ) + .foregroundStyle(Color(.label)) Text( authService.authenticationFlow == .signUp - ? authService.string - .emailLoginFlowLabel - : authService.string.emailSignUpFlowLabel + ? authService.string.emailLoginFlowLabel + : authService.string.emailSignUpFlowLabel ) .fontWeight(.semibold) .foregroundColor(.blue) } - .accessibilityIdentifier("switch-auth-flow") } + .accessibilityIdentifier("switch-auth-flow") } } diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailLinkView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailLinkView.swift index c86c33d64f..14690cda82 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailLinkView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailLinkView.swift @@ -39,7 +39,7 @@ extension EmailLinkView: View { VStack(spacing: 24) { AuthTextField( text: $email, - localizedTitle: "Send a sign-in link to your email", + label: authService.string.signInLinkEmailFieldLabel, prompt: authService.string.emailInputLabel, keyboardType: .emailAddress, contentType: .emailAddress, diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift index 757e588f26..19589bacaa 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift @@ -38,7 +38,7 @@ struct EnterPhoneNumberView: View { AuthTextField( text: $phoneNumber, - localizedTitle: "Phone", + label: authService.string.phoneFieldLabel, prompt: authService.string.enterPhoneNumberPlaceholder, keyboardType: .phonePad, contentType: .telephoneNumber, diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterVerificationCodeView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterVerificationCodeView.swift index 54e4f996fb..0356d3120c 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterVerificationCodeView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterVerificationCodeView.swift @@ -33,7 +33,7 @@ struct EnterVerificationCodeView: View { VStack(spacing: 32) { VStack(spacing: 16) { VStack(spacing: 8) { - Text("We sent a code to \(fullPhoneNumber)") + Text(authService.string.sentCodeMessage(phoneNumber: fullPhoneNumber)) .font(.subheadline) .foregroundStyle(.secondary) .multilineTextAlignment(.center) @@ -42,7 +42,7 @@ struct EnterVerificationCodeView: View { Button { authService.navigator.pop() } label: { - Text("Change number") + Text(authService.string.changeNumberButtonLabel) .font(.caption) .frame(maxWidth: .infinity, alignment: .leading) } diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/MFAEnrolmentView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/MFAEnrolmentView.swift index f53da9da72..8f0185b99f 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/MFAEnrolmentView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/MFAEnrolmentView.swift @@ -370,8 +370,8 @@ extension MFAEnrolmentView: View { AuthTextField( text: $phoneNumber, - localizedTitle: "Phone Number", - prompt: "Enter phone number", + label: authService.string.phoneNumberFieldLabel, + prompt: authService.string.enterPhoneNumberPrompt, keyboardType: .phonePad, contentType: .telephoneNumber, onChange: { _ in } @@ -386,8 +386,8 @@ extension MFAEnrolmentView: View { AuthTextField( text: $displayName, - localizedTitle: "Display Name", - prompt: "Enter display name for this device", + label: authService.string.displayNameFieldLabel, + prompt: authService.string.enterDisplayNameForDevicePrompt, leading: { Image(systemName: "person") } @@ -432,7 +432,7 @@ extension MFAEnrolmentView: View { AuthTextField( text: $verificationCode, - localizedTitle: "Verification Code", + label: authService.string.verificationCodeFieldLabel, prompt: "Enter 6-digit code", keyboardType: .numberPad, contentType: .oneTimeCode, @@ -577,8 +577,8 @@ extension MFAEnrolmentView: View { AuthTextField( text: $displayName, - localizedTitle: "Display Name", - prompt: "Enter display name for this authenticator", + label: authService.string.displayNameFieldLabel, + prompt: authService.string.enterDisplayNameForAuthenticatorPrompt, leading: { Image(systemName: "person") } @@ -587,8 +587,8 @@ extension MFAEnrolmentView: View { AuthTextField( text: $totpCode, - localizedTitle: "Verification Code", - prompt: "Enter code from app", + label: authService.string.verificationCodeFieldLabel, + prompt: authService.string.enterCodeFromAppPrompt, keyboardType: .numberPad, contentType: .oneTimeCode, leading: { diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/PasswordRecoveryView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/PasswordRecoveryView.swift index 5c8296ed1a..f14346d4d2 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/PasswordRecoveryView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/PasswordRecoveryView.swift @@ -40,7 +40,7 @@ extension PasswordRecoveryView: View { VStack(spacing: 24) { AuthTextField( text: $email, - localizedTitle: "Send a password recovery link to your email", + label: authService.string.passwordRecoveryEmailFieldLabel, prompt: authService.string.emailInputLabel, keyboardType: .emailAddress, contentType: .emailAddress, diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/UpdatePasswordView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/UpdatePasswordView.swift index b2e7921797..1e54cfe4d6 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/UpdatePasswordView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/UpdatePasswordView.swift @@ -45,7 +45,7 @@ extension UpdatePasswordView: View { VStack(spacing: 24) { AuthTextField( text: $password, - localizedTitle: "Type new password", + label: "Type new password", prompt: authService.string.passwordInputLabel, contentType: .password, sensitive: true, @@ -58,7 +58,7 @@ extension UpdatePasswordView: View { AuthTextField( text: $confirmPassword, - localizedTitle: "Retype new password", + label: "Retype new password", prompt: authService.string.confirmPasswordInputLabel, contentType: .password, sensitive: true, diff --git a/FirebaseSwiftUI/FirebaseAuthUIComponents/Sources/Components/AuthTextField.swift b/FirebaseSwiftUI/FirebaseAuthUIComponents/Sources/Components/AuthTextField.swift index 9c3247c6c7..628dd15462 100644 --- a/FirebaseSwiftUI/FirebaseAuthUIComponents/Sources/Components/AuthTextField.swift +++ b/FirebaseSwiftUI/FirebaseAuthUIComponents/Sources/Components/AuthTextField.swift @@ -31,7 +31,7 @@ public struct AuthTextField: View { @State var obscured: Bool = true @Binding var text: String - let localizedTitle: String + let label: String let prompt: String var textAlignment: TextAlignment = .leading var keyboardType: UIKeyboardType = .default @@ -44,7 +44,7 @@ public struct AuthTextField: View { private let leading: () -> Leading? public init(text: Binding, - localizedTitle: String, + label: String, prompt: String, textAlignment: TextAlignment = .leading, keyboardType: UIKeyboardType = .default, @@ -56,7 +56,7 @@ public struct AuthTextField: View { onChange: ((String) -> Void)? = nil, @ViewBuilder leading: @escaping () -> Leading? = { EmptyView() }) { _text = text - self.localizedTitle = localizedTitle + self.label = label self.prompt = prompt self.textAlignment = textAlignment self.keyboardType = keyboardType @@ -75,17 +75,17 @@ public struct AuthTextField: View { public var body: some View { VStack(alignment: .leading) { - Text(localizedTitle) + Text(LocalizedStringResource(stringLiteral: label)) HStack(spacing: 8) { leading() Group { if isSecureTextField { ZStack(alignment: .trailing) { - SecureField(localizedTitle, text: $text, prompt: Text(prompt)) + SecureField(label, text: $text, prompt: Text(prompt)) .opacity(obscured ? 1 : 0) .focused($isFocused) .frame(height: 24) - TextField(localizedTitle, text: $text, prompt: Text(prompt)) + TextField(label, text: $text, prompt: Text(prompt)) .opacity(obscured ? 0 : 1) .focused($isFocused) .frame(height: 24) @@ -106,7 +106,7 @@ public struct AuthTextField: View { } } else { TextField( - localizedTitle, + label, text: $text, prompt: Text(prompt) ) diff --git a/FirebaseSwiftUI/FirebaseGoogleSwiftUI/Sources/Views/SignInWithGoogleButton.swift b/FirebaseSwiftUI/FirebaseGoogleSwiftUI/Sources/Views/SignInWithGoogleButton.swift index dffb56123d..e967466813 100644 --- a/FirebaseSwiftUI/FirebaseGoogleSwiftUI/Sources/Views/SignInWithGoogleButton.swift +++ b/FirebaseSwiftUI/FirebaseGoogleSwiftUI/Sources/Views/SignInWithGoogleButton.swift @@ -36,7 +36,7 @@ public struct SignInWithGoogleButton { extension SignInWithGoogleButton: View { public var body: some View { AuthProviderButton( - label: "Sign in with Google", + label: authService.string.googleLoginButtonLabel, style: .google, accessibilityId: "sign-in-with-google-button" ) { diff --git a/FirebaseSwiftUI/FirebaseOAuthSwiftUI/Sources/Views/GenericOAuthButton.swift b/FirebaseSwiftUI/FirebaseOAuthSwiftUI/Sources/Views/GenericOAuthButton.swift index b7af99e5e7..e8e7a8dac1 100644 --- a/FirebaseSwiftUI/FirebaseOAuthSwiftUI/Sources/Views/GenericOAuthButton.swift +++ b/FirebaseSwiftUI/FirebaseOAuthSwiftUI/Sources/Views/GenericOAuthButton.swift @@ -30,7 +30,7 @@ extension GenericOAuthButton: View { public var body: some View { guard let oauthProvider = provider as? OAuthProviderSwift else { return AnyView( - Text("Invalid OAuth Provider") + Text(authService.string.invalidOAuthProviderError) .foregroundColor(.red) ) } diff --git a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift index 8af609241e..5f24d7cf35 100644 --- a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift +++ b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift @@ -30,7 +30,7 @@ public struct PhoneAuthButtonView { extension PhoneAuthButtonView: View { public var body: some View { AuthProviderButton( - label: "Sign in with Phone", + label: authService.string.phoneLoginButtonLabel, style: .phone, accessibilityId: "sign-in-with-phone-button" ) { diff --git a/FirebaseSwiftUI/FirebaseTwitterSwiftUI/Sources/Views/SignInWithTwitterButton.swift b/FirebaseSwiftUI/FirebaseTwitterSwiftUI/Sources/Views/SignInWithTwitterButton.swift index a874819f02..28d67e9c60 100644 --- a/FirebaseSwiftUI/FirebaseTwitterSwiftUI/Sources/Views/SignInWithTwitterButton.swift +++ b/FirebaseSwiftUI/FirebaseTwitterSwiftUI/Sources/Views/SignInWithTwitterButton.swift @@ -29,7 +29,7 @@ public struct SignInWithTwitterButton { extension SignInWithTwitterButton: View { public var body: some View { AuthProviderButton( - label: "Sign in with X", + label: authService.string.twitterLoginButtonLabel, style: .twitter, accessibilityId: "sign-in-with-twitter-button" ) { diff --git a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/project.pbxproj b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/project.pbxproj index 7b274a794d..1369624ea2 100644 --- a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/project.pbxproj +++ b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/project.pbxproj @@ -462,7 +462,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"FirebaseSwiftUIExample/Preview Content\""; - DEVELOPMENT_TEAM = 3G33A99C47; + DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = FirebaseSwiftUIExample/Info.plist; @@ -478,7 +478,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = aob.flutter.plugins.firebase.auth.example; + PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.firebase.auth.example; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 6.0; @@ -511,7 +511,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = aob.flutter.plugins.firebase.auth.example; + PRODUCT_BUNDLE_IDENTIFIER = io.flutter.plugins.firebase.auth.example; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 6.0; diff --git a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift index 34af70a631..ee17bf6782 100644 --- a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift +++ b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift @@ -39,6 +39,7 @@ struct ContentView: View { actionCodeSettings.linkDomain = "flutterfire-e2e-tests.firebaseapp.com" actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!) let configuration = AuthConfiguration( + logo: .icLineLogo, tosUrl: URL(string: "https://example.com/tos"), privacyPolicyUrl: URL(string: "https://example.com/privacy"), emailLinkSignInActionCodeSettings: actionCodeSettings, diff --git a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/Info.plist b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/Info.plist index e5d2f1e122..bea005ea42 100644 --- a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/Info.plist +++ b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/Info.plist @@ -41,5 +41,10 @@ fetch remote-notification + CFBundleLocalizations + + en + es + From c4bd5fc5973545768abfc21d5dd88dea475d8b4e Mon Sep 17 00:00:00 2001 From: Ademola Fadumo Date: Wed, 5 Nov 2025 11:07:12 +0100 Subject: [PATCH 2/7] feat: optional logo and locale, es, de, fr translations --- .../Sources/Services/AuthConfiguration.swift | 3 + .../Sources/Services/AuthService.swift | 2 +- .../Sources/Strings/Localizable.xcstrings | 6244 +++++++++++------ .../Sources/Utils/StringUtils.swift | 29 +- .../App/ContentView.swift | 2 +- .../FirebaseSwiftUIExample/Info.plist | 2 + 6 files changed, 4168 insertions(+), 2114 deletions(-) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift index 3dcf1208e1..3c45c49849 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift @@ -22,6 +22,7 @@ public struct AuthConfiguration { public let interactiveDismissEnabled: Bool public let shouldAutoUpgradeAnonymousUsers: Bool public let customStringsBundle: Bundle? + public let locale: Locale? public let tosUrl: URL? public let privacyPolicyUrl: URL? public let emailLinkSignInActionCodeSettings: ActionCodeSettings? @@ -39,6 +40,7 @@ public struct AuthConfiguration { interactiveDismissEnabled: Bool = true, shouldAutoUpgradeAnonymousUsers: Bool = false, customStringsBundle: Bundle? = nil, + locale: Locale? = nil, tosUrl: URL? = nil, privacyPolicyUrl: URL? = nil, emailLinkSignInActionCodeSettings: ActionCodeSettings? = nil, @@ -52,6 +54,7 @@ public struct AuthConfiguration { self.interactiveDismissEnabled = interactiveDismissEnabled self.shouldAutoUpgradeAnonymousUsers = shouldAutoUpgradeAnonymousUsers self.customStringsBundle = customStringsBundle + self.locale = locale self.tosUrl = tosUrl self.privacyPolicyUrl = privacyPolicyUrl self.emailLinkSignInActionCodeSettings = emailLinkSignInActionCodeSettings diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift index 8d2a75f75d..999654a72e 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift @@ -109,7 +109,7 @@ public final class AuthService { public init(configuration: AuthConfiguration = AuthConfiguration(), auth: Auth = Auth.auth()) { self.auth = auth self.configuration = configuration - string = StringUtils(bundle: configuration.customStringsBundle ?? Bundle.module) + string = StringUtils(bundle: configuration.customStringsBundle ?? Bundle.module, locale: configuration.locale) listenerManager = AuthListenerManager(auth: auth, authEnvironment: self) FirebaseApp.registerLibrary("firebase-ui-ios", withVersion: FirebaseAuthSwiftUIVersion.version) } diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Strings/Localizable.xcstrings b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Strings/Localizable.xcstrings index bf5f780f06..9f57074e39 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Strings/Localizable.xcstrings +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Strings/Localizable.xcstrings @@ -1,2933 +1,4961 @@ { - "sourceLanguage" : "en", - "strings" : { - "%@" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "%@" + "sourceLanguage": "en", + "strings": { + "%@": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "%@" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "%@" + "en": { + "stringUnit": { + "state": "translated", + "value": "%@" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "%@" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "%@" + } + } + } + }, + "••••••%@": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "••••••%@" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "••••••%@" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "••••••%@" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "••••••%@" + } + } + } + }, + "Account: %@": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Konto: %@" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Account: %@" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Cuenta: %@" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Compte : %@" + } + } + } + }, + "AccountDisabledError": { + "comment": "Error message displayed when the account is disabled. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "migrated", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Diese E-Mail-Adresse gehört zu einem deaktivierten Konto." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "That email address is for an account that has been disabled." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Esa dirección de correo es de una cuenta que ha sido deshabilitada." + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Cette adresse e-mail correspond à un compte qui a été désactivé." + } + } + } + }, + "ActionCantBeUndone": { + "comment": "Alert message shown before account deletion.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Diese Aktion kann nicht rückgängig gemacht werden" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "This action can't be undone" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Esta acción no se puede deshacer" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Cette action ne peut pas être annulée" + } + } + } + }, + "Add an extra layer of security to your account": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Füge deinem Konto eine zusätzliche Sicherheitsebene hinzu" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Add an extra layer of security to your account" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Agrega una capa adicional de seguridad a tu cuenta" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Ajoute une couche de sécurité supplémentaire à ton compte" + } + } + } + }, + "Add Another Method": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Weitere Methode hinzufügen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Add Another Method" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Agregar otro método" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Ajouter une autre méthode" + } + } + } + }, + "AddPasswordAlertMessage": { + "comment": "Alert message shown when adding account password.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Um ein Passwort zu deinem Konto hinzuzufügen, musst du dich erneut anmelden." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "To add password to your account, you will need to sign in again." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Para agregar una contraseña a tu cuenta, deberás iniciar sesión nuevamente." + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Pour ajouter un mot de passe à ton compte, tu devras te reconnecter." + } + } + } + }, + "AddPasswordTitle": { + "comment": "Controller title shown when adding password to account.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort hinzufügen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Add password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Agregar contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Ajouter un mot de passe" + } + } + } + }, + "Already have an account?": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Hast du bereits ein Konto?" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Already have an account?" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¿Ya tienes una cuenta?" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Tu as déjà un compte ?" + } + } + } + }, + "AS_AddPassword": { + "comment": "Account Settings cell title Add Password.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort hinzufügen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Add password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Agregar contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Ajouter un mot de passe" + } + } + } + }, + "AS_ChangePassword": { + "comment": "Account Settings cell title Change Password.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort ändern" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Change password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Cambiar contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Changer le mot de passe" + } + } + } + }, + "AS_DeleteAccount": { + "comment": "Account Settings cell title Delete Account.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Konto löschen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Delete Account" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Eliminar cuenta" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Supprimer le compte" + } + } + } + }, + "AS_Email": { + "comment": "Account Settings cell title Email. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "E-Mail" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Email" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Correo" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "E-mail" + } + } + } + }, + "AS_Name": { + "comment": "Account Settings cell title Name.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Name" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Name" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Nombre" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Nom" + } + } + } + }, + "AS_SectionLinkedAccounts": { + "comment": "Account Settings section title Linked Accounts.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Verknüpfte Konten" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Linked Accounts" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Cuentas vinculadas" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Comptes liés" + } + } + } + }, + "AS_SectionProfile": { + "comment": "Account Settings section title Profile.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Profil" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Profile" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Perfil" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Profil" + } + } + } + }, + "AS_SectionSecurity": { + "comment": "Account Settings section title Security.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Sicherheit" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Security" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Seguridad" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Sécurité" + } + } + } + }, + "AS_SignOut": { + "comment": "Account Settings cell title Sign Out.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Abmelden" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign Out" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Cerrar sesión" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se déconnecter" + } + } + } + }, + "Authenticating...": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Authentifizierung läuft..." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Authenticating..." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Autenticando..." + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Authentification..." + } + } + } + }, + "Authentication Method": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Authentifizierungsmethode" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Authentication Method" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Método de autenticación" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Méthode d'authentification" + } + } + } + }, + "Authenticator App": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Authentifizierungs-App" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Authenticator App" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Aplicación de autenticación" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Application d'authentification" + } + } + } + }, + "AuthPickerTitle": { + "comment": "Title for auth picker screen.", + "extractionState": "stale", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Mit Firebase anmelden" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign in with Firebase" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión con Firebase" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se connecter avec Firebase" + } + } + } + }, + "Back": { + "comment": "Back button title.", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Zurück" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Back" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Atrás" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Retour" + } + } + } + }, + "Cancel": { + "comment": "Cancel button title.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Abbrechen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Cancel" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Cancelar" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Annuler" + } + } + } + }, + "CannotAuthenticateError": { + "comment": "Error message displayed when the app cannot authenticate user's account.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Dieser Kontotyp wird von dieser App nicht unterstützt" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "This type of account isn't supported by this app" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Este tipo de cuenta no es compatible con esta aplicación" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Ce type de compte n'est pas pris en charge par cette application" + } + } + } + }, + "CantFindProvider": { + "comment": "Error message displayed when FUIAuth is not configured with third party provider. Parameter is value of provider (e g Google, Facebook etc)", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Anbieter für %@ kann nicht gefunden werden." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Can't find provider for %@." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "No se puede encontrar el proveedor para %@." + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Impossible de trouver le fournisseur pour %@." + } + } + } + }, + "Change number": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Nummer ändern" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Change number" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Cambiar número" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Changer le numéro" + } + } + } + }, + "Choose Authentication Method": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Authentifizierungsmethode wählen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Choose Authentication Method" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Elige el método de autenticación" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Choisir la méthode d'authentification" + } + } + } + }, + "Choose verification method:": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Verifizierungsmethode wählen:" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Choose verification method:" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Elige el método de verificación:" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Choisis la méthode de vérification :" + } + } + } + }, + "ChoosePassword": { + "comment": "Placeholder for the password text field in a sign up form.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort wählen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Choose password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Elegir contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Choisis un mot de passe" + } + } + } + }, + "Close": { + "comment": "Alert button title Close.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Schließen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Close" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Cerrar" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Fermer" + } + } + } + }, + "Complete Setup": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Einrichtung abschließen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Complete Setup" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Completar configuración" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Terminer la configuration" + } + } + } + }, + "Complete Sign-In": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Anmeldung abschließen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Complete Sign-In" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Completar inicio de sesión" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Terminer la connexion" + } + } + } + }, + "Complete sign-in with your second factor": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Schließe die Anmeldung mit deinem zweiten Faktor ab" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Complete sign-in with your second factor" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Completa el inicio de sesión con tu segundo factor" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Termine la connexion avec ton deuxième facteur" + } + } + } + }, + "ConfirmEmail": { + "comment": "Title of confirm email label.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "E-Mail bestätigen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Confirm Email" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Confirmar correo" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Confirmer l'e-mail" + } + } + } + }, + "Confirm Password": { + "comment": "Field label for confirming password", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort bestätigen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Confirm Password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Confirmar contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Confirmer le mot de passe" + } + } + } + }, + "ConfirmPasswordInputLabel": { + "comment": "Input label for confirming password when signing up", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort bestätigen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Confirm Password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Confirmar contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Confirmer le mot de passe" + } + } + } + }, + "Copied to clipboard!": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "In die Zwischenablage kopiert!" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Copied to clipboard!" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¡Copiado al portapapeles!" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Copié dans le presse-papiers !" + } + } + } + }, + "Delete": { + "comment": "Text of Delete action button.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Löschen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Delete" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Eliminar" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Supprimer" + } + } + } + }, + "Delete Account": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Konto löschen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Delete Account" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Eliminar cuenta" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Supprimer le compte" + } + } + } + }, + "Delete Account?": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Konto löschen?" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Delete Account?" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¿Eliminar cuenta?" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Supprimer le compte ?" + } + } + } + }, + "DeleteAccountBody": { + "comment": "Alert message body shown to confirm account deletion action.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Dies löscht alle mit deinem Konto verbundenen Daten und kann nicht rückgängig gemacht werden. Du musst dich erneut anmelden, um diese Aktion abzuschließen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "This will erase all data associated with your account, and can't be undone You will need to sign in again to complete this action" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Esto borrará todos los datos asociados con tu cuenta y no se puede deshacer. Deberás iniciar sesión nuevamente para completar esta acción" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Cela effacera toutes les données associées à ton compte et ne peut pas être annulé. Tu devras te reconnecter pour effectuer cette action" + } + } + } + }, + "DeleteAccountConfirmationMessage": { + "comment": "Explanation message shown before deleting account.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Dies löscht alle mit deinem Konto verbundenen Daten und kann nicht rückgängig gemacht werden. Bist du sicher, dass du dein Konto löschen möchtest?" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "This will erase all data associated with your account, and can't be undone. Are you sure you want to delete your account?" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Esto borrará todos los datos asociados con tu cuenta y no se puede deshacer. ¿Estás seguro de que deseas eliminar tu cuenta?" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Cela effacera toutes les données associées à ton compte et ne peut pas être annulé. Es-tu sûr de vouloir supprimer ton compte ?" + } + } + } + }, + "DeleteAccountConfirmationTitle": { + "comment": "Alert message title shown to confirm account deletion action.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Konto löschen?" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Delete Account?" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¿Eliminar cuenta?" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Supprimer le compte ?" + } + } + } + }, + "DeleteAccountControllerTitle": { + "comment": "Title of Controller shown before deleting account", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Konto löschen" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Delete account" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Eliminar cuenta" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Supprimer le compte" + } + } + } + }, + "Display Name": { + "comment": "Field label for display name", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Anzeigename" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Display Name" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Nombre para mostrar" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Nom affiché" + } + } + } + }, + "Don't have an account yet?": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Hast du noch kein Konto?" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Don't have an account yet?" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¿Aún no tienes una cuenta?" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Tu n'as pas encore de compte ?" + } + } + } + }, + "EditEmailTitle": { + "comment": "Controller title shown when editing account email. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "E-Mail bearbeiten" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Edit email" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Editar correo" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Modifier l'e-mail" + } + } + } + }, + "EditNameTitle": { + "comment": "Controller title shown when editing account name.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Name bearbeiten" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Edit name" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Editar nombre" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Modifier le nom" + } + } + } + }, + "EditPasswordAlertMessage": { + "comment": "Alert message shown when editing account password.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Um das Passwort deines Kontos zu ändern, musst du dich erneut anmelden." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "To change password to your account, you will need to sign in again." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Para cambiar la contraseña de tu cuenta, deberás iniciar sesión nuevamente." + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Pour modifier le mot de passe de ton compte, tu devras te reconnecter." + } + } + } + }, + "EditPasswordTitle": { + "comment": "Controller title shown when editing password to account.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort ändern" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Change password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Cambiar contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Changer le mot de passe" + } + } + } + }, + "Email": { + "comment": "Field label for email", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "E-Mail" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Email" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Correo" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "E-mail" + } + } + } + }, + "EmailAlreadyInUseError": { + "comment": "Error message displayed when the email address is already in use. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "migrated", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Die E-Mail-Adresse wird bereits von einem anderen Konto verwendet." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "The email address is already in use by another account." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "La dirección de correo ya está en uso por otra cuenta." + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Cette adresse e-mail est déjà utilisée par un autre compte." + } + } + } + }, + "Enter code from app": { + "comment": "Prompt for entering code from authenticator app", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Code aus der App eingeben" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter code from app" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa el código de la aplicación" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis le code de l'application" + } + } + } + }, + "Enter display name for this authenticator": { + "comment": "Prompt for entering display name for authenticator", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Anzeigename für diesen Authentifikator eingeben" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter display name for this authenticator" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa el nombre para mostrar de este autenticador" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis le nom affiché pour cet authentificateur" + } + } + } + }, + "Enter display name for this device": { + "comment": "Prompt for entering display name for device", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Anzeigename für dieses Gerät eingeben" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter display name for this device" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa el nombre para mostrar de este dispositivo" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis le nom affiché pour cet appareil" + } + } + } + }, + "Enter phone number": { + "comment": "Prompt for entering phone number", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Telefonnummer eingeben" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter phone number" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa el número de teléfono" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis le numéro de téléphone" + } + } + } + }, + "EmailLinkSignInLabel": { + "comment": "Button label to push user to email link sign-in", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Lieber mit E-Mail-Link anmelden?" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Prefer Email link sign-in?" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¿Prefieres iniciar sesión con enlace por correo?" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Préfères-tu la connexion par lien e-mail ?" + } + } + } + }, + "EmailLinkSignInTitle": { + "comment": "Sign in with email link View title", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Mit E-Mail-Link anmelden" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign in with email link" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión con enlace por correo" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se connecter avec un lien e-mail" + } + } + } + }, + "EmailsDontMatch": { + "comment": "Error message displayed when after re-authorization current user's email and re-authorized user's email doesn't match. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "E-Mails stimmen nicht überein" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Emails don't match" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Los correos no coinciden" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Les e-mails ne correspondent pas" + } + } + } + }, + "EmailSentConfirmationMessage": { + "comment": "Message displayed after email is sent. The placeholder is the email address that the email is sent to.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Eine Anmelde-E-Mail mit zusätzlichen Anweisungen wurde an %@ gesendet. Überprüfe deine E-Mails, um die Anmeldung abzuschließen." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "A sign-in email with additional instructions was sent to %@. Check your email to complete sign-in." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Se envió un correo de inicio de sesión con instrucciones adicionales a %@. Revisa tu correo para completar el inicio de sesión." + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Un e-mail de connexion avec des instructions supplémentaires a été envoyé à %@. Vérifie tes e-mails pour terminer la connexion." + } + } + } + }, + "Enrolled Methods": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Registrierte Methoden" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enrolled Methods" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Métodos registrados" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Méthodes inscrites" + } + } + } + }, + "Enrolled: %@": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Registriert: %@" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enrolled: %@" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Registrado: %@" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Inscrit : %@" + } + } + } + }, + "Enter 6-digit code": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "6-stelligen Code eingeben" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter 6-digit code" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa el código de 6 dígitos" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis le code à 6 chiffres" } } } }, - "••••••%@" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "••••••%@" + "Enter the 6-digit code from your authenticator app": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Gib den 6-stelligen Code aus deiner Authentifizierungs-App ein" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "••••••%@" + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter the 6-digit code from your authenticator app" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa el código de 6 dígitos de tu aplicación de autenticación" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis le code à 6 chiffres de ton application d'authentification" } } } }, - "Account: %@" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Account: %@" + "Enter Verification Code": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Bestätigungscode eingeben" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter Verification Code" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa el código de verificación" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cuenta: %@" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis le code de vérification" } } } }, - "AccountDisabledError" : { - "comment" : "Error message displayed when the account is disabled. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "That email address is for an account that has been disabled." + "Enter Your Phone Number": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Gib deine Telefonnummer ein" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Esa dirección de correo es de una cuenta que ha sido deshabilitada." + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter Your Phone Number" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa tu número de teléfono" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis ton numéro de téléphone" } } } }, - "ActionCantBeUndone" : { - "comment" : "Alert message shown before account deletion.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "This action can't be undone" + "EnterYourEmail": { + "comment": "Title for email entry screen, email text field placeholder. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Gib deine E-Mail ein" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter your email" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa tu correo" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Esta acción no se puede deshacer" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis ton e-mail" } } } }, - "Add an extra layer of security to your account" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Add an extra layer of security to your account" + "EnterYourPassword": { + "comment": "Password text field placeholder.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Gib dein Passwort ein" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Agrega una capa adicional de seguridad a tu cuenta" + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter your password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa tu contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis ton mot de passe" } } } }, - "Add Another Method" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Add Another Method" + "Error": { + "comment": "Alert title Error.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Fehler" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Error" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Error" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Agregar otro método" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Erreur" } } } }, - "AddPasswordAlertMessage" : { - "comment" : "Alert message shown when adding account password.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "To add password to your account, you will need to sign in again." + "ExistingAccountTitle": { + "comment": "Title of an alert shown to an existing user coming back to the app.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Du hast bereits ein Konto" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Para agregar una contraseña a tu cuenta, deberás iniciar sesión nuevamente." + "en": { + "stringUnit": { + "state": "translated", + "value": "You already have an account" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ya tienes una cuenta" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Tu as déjà un compte" } } } }, - "AddPasswordTitle" : { - "comment" : "Controller title shown when adding password to account.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Add password" + "FirstAndLastName": { + "comment": "Name text field placeholder.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Vor- und Nachname" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "First & last name" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Nombre y apellido" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Agregar contraseña" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Prénom et nom" } } } }, - "Already have an account?" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Already have an account?" + "ForgotPassword": { + "comment": "Button text for 'Forgot Password' action.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort-Wiederherstellungs-E-Mail senden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¿Ya tienes una cuenta?" + "en": { + "stringUnit": { + "state": "translated", + "value": "Send password recovery email" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviar correo de recuperación de contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Envoyer un e-mail de récupération de mot de passe" } } } }, - "AS_AddPassword" : { - "comment" : "Account Settings cell title Add Password.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Add password" + "ForgotPasswordTitle": { + "comment": "Title of forgot password button.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Probleme beim Anmelden?" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Trouble signing in?" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¿Problemas para iniciar sesión?" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Agregar contraseña" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Problème de connexion ?" } } } }, - "AS_ChangePassword" : { - "comment" : "Account Settings cell title Change Password.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Change password" + "Get Started": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Loslegen" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cambiar contraseña" + "en": { + "stringUnit": { + "state": "translated", + "value": "Get Started" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Comenzar" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Commencer" } } } }, - "AS_DeleteAccount" : { - "comment" : "Account Settings cell title Delete Account.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Delete Account" + "InvalidEmailError": { + "comment": "Error message displayed when user enters an invalid email address. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "migrated", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Diese E-Mail-Adresse ist nicht korrekt." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "That email address isn't correct." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Esa dirección de correo no es correcta." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eliminar cuenta" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Cette adresse e-mail n'est pas correcte." } } } }, - "AS_Email" : { - "comment" : "Account Settings cell title Email. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Email" + "Invalid OAuth Provider": { + "comment": "Error message displayed when OAuth provider configuration is invalid.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Ungültiger OAuth-Anbieter" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Correo" + "en": { + "stringUnit": { + "state": "translated", + "value": "Invalid OAuth Provider" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Proveedor OAuth inválido" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Fournisseur OAuth invalide" } } } }, - "AS_Name" : { - "comment" : "Account Settings cell title Name.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Name" + "InvalidPasswordError": { + "comment": "Error message displayed when user enters an empty password.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort darf nicht leer sein." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Password cannot be empty." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "La contraseña no puede estar vacía." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nombre" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Le mot de passe ne peut pas être vide." } } } }, - "AS_SectionLinkedAccounts" : { - "comment" : "Account Settings section title Linked Accounts.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Linked Accounts" + "Login": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Anmelden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cuentas vinculadas" + "en": { + "stringUnit": { + "state": "translated", + "value": "Login" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Connexion" } } } }, - "AS_SectionProfile" : { - "comment" : "Account Settings section title Profile.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Profile" + "Manage Two-Factor Authentication": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Zwei-Faktor-Authentifizierung verwalten" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Manage Two-Factor Authentication" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Administrar autenticación de dos factores" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Perfil" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Gérer l'authentification à deux facteurs" } } } }, - "AS_SectionSecurity" : { - "comment" : "Account Settings section title Security.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Security" + "Manage your authentication methods": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Verwalte deine Authentifizierungsmethoden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Seguridad" + "en": { + "stringUnit": { + "state": "translated", + "value": "Manage your authentication methods" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Administra tus métodos de autenticación" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Gère tes méthodes d'authentification" } } } }, - "AS_SignOut" : { - "comment" : "Account Settings cell title Sign Out.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign Out" + "Manual Entry Key:": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Manueller Eingabeschlüssel:" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Manual Entry Key:" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Clave de entrada manual:" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cerrar sesión" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Clé de saisie manuelle :" } } } }, - "Authenticating..." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Authenticating..." + "MFA is not enabled in the current configuration. Please contact your administrator.": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "MFA ist in der aktuellen Konfiguration nicht aktiviert. Bitte kontaktiere deinen Administrator." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Autenticando..." + "en": { + "stringUnit": { + "state": "translated", + "value": "MFA is not enabled in the current configuration. Please contact your administrator." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "MFA no está habilitado en la configuración actual. Por favor, contacta a tu administrador." + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "L'authentification multifacteur n'est pas activée dans la configuration actuelle. Contacte ton administrateur." } } } }, - "Authentication Method" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Authentication Method" + "Multi-Factor Authentication Disabled": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Mehr-Faktor-Authentifizierung deaktiviert" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Multi-Factor Authentication Disabled" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Autenticación multifactor deshabilitada" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Método de autenticación" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Authentification multifacteur désactivée" } } } }, - "Authenticator App" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Authenticator App" + "Name": { + "comment": "Label next to a name text field.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Name" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Aplicación de autenticación" + "en": { + "stringUnit": { + "state": "translated", + "value": "Name" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Nombre" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Nom" } } } }, - "AuthPickerTitle" : { - "comment" : "Title for auth picker screen.", - "extractionState" : "stale", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign in with Firebase" + "Next": { + "comment": "Next button title.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Weiter" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Next" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Siguiente" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión con Firebase" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Suivant" } } } }, - "Back" : { - "comment" : "Back button title.", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Back" + "No Authentication Methods": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Keine Authentifizierungsmethoden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Atrás" + "en": { + "stringUnit": { + "state": "translated", + "value": "No Authentication Methods" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Sin métodos de autenticación" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Aucune méthode d'authentification" } } } }, - "Cancel" : { - "comment" : "Cancel button title.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cancel" + "No Authentication Methods Available": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Keine Authentifizierungsmethoden verfügbar" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "No Authentication Methods Available" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "No hay métodos de autenticación disponibles" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cancelar" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Aucune méthode d'authentification disponible" } } } }, - "CannotAuthenticateError" : { - "comment" : "Error message displayed when the app cannot authenticate user's account.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "This type of account isn't supported by this app" + "No MFA methods are configured as allowed. Please contact your administrator.": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Keine MFA-Methoden sind als erlaubt konfiguriert. Bitte kontaktiere deinen Administrator." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Este tipo de cuenta no es compatible con esta aplicación" + "en": { + "stringUnit": { + "state": "translated", + "value": "No MFA methods are configured as allowed. Please contact your administrator." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "No hay métodos MFA configurados como permitidos. Por favor, contacta a tu administrador." + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Aucune méthode d'authentification multifacteur n'est configurée comme autorisée. Contacte ton administrateur." } } } }, - "CantFindProvider" : { - "comment" : "Error message displayed when FUIAuth is not configured with third party provider. Parameter is value of provider (e g Google, Facebook etc)", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Can't find provider for %@." + "OK": { + "comment": "OK button title.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "OK" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "OK" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Aceptar" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "No se puede encontrar el proveedor para %@." + "fr": { + "stringUnit": { + "state": "translated", + "value": "OK" } } } }, - "Change number" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Change number" + "Password": { + "comment": "Field label for password", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cambiar número" + "en": { + "stringUnit": { + "state": "translated", + "value": "Password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Mot de passe" } } } }, - "Choose Authentication Method" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Choose Authentication Method" + "PasswordRecoveryEmailSentMessage": { + "comment": "Message displayed when the email for password recovery has been sent.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Folge den Anweisungen, die an %@ gesendet wurden, um dein Passwort wiederherzustellen." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Follow the instructions sent to %@ to recover your password." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Sigue las instrucciones enviadas a %@ para recuperar tu contraseña." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Elige el método de autenticación" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Suis les instructions envoyées à %@ pour récupérer ton mot de passe." } } } }, - "Choose verification method:" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Choose verification method:" + "PasswordRecoveryEmailSentTitle": { + "comment": "Title of a message displayed when the email for password recovery has been sent. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Überprüfe deine E-Mails" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Elige el método de verificación:" + "en": { + "stringUnit": { + "state": "translated", + "value": "Check your email" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Revisa tu correo" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Vérifie tes e-mails" } } } }, - "ChoosePassword" : { - "comment" : "Placeholder for the password text field in a sign up form.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Choose password" + "PasswordRecoveryMessage": { + "comment": "Explanation on how the password of an account can be recovered. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Erhalte Anweisungen an diese E-Mail, die erklären, wie du dein Passwort zurücksetzen kannst." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Get instructions sent to this email that explain how to reset your password." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Recibe instrucciones enviadas a este correo que explican cómo restablecer tu contraseña." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Elegir contraseña" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Reçois des instructions envoyées à cet e-mail qui expliquent comment réinitialiser ton mot de passe." } } } }, - "Close" : { - "comment" : "Alert button title Close.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Close" + "PasswordRecoveryTitle": { + "comment": "Title for password recovery screen.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort wiederherstellen" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cerrar" + "en": { + "stringUnit": { + "state": "translated", + "value": "Recover password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Recuperar contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Récupérer le mot de passe" } } } }, - "Complete Setup" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Complete Setup" + "PasswordVerificationMessage": { + "comment": "Message to explain to the user that password is needed for an account with this email address.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Du hast bereits %@ verwendet, um dich anzumelden. Gib dein Passwort für dieses Konto ein." + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "You've already used %@ to sign in. Enter your password for that account." + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ya has usado %@ para iniciar sesión. Ingresa tu contraseña para esa cuenta." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Completar configuración" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Tu as déjà utilisé %@ pour te connecter. Saisis ton mot de passe pour ce compte." } } } }, - "Complete Sign-In" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Complete Sign-In" + "Phone": { + "comment": "Field label for phone", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Telefon" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Completar inicio de sesión" + "en": { + "stringUnit": { + "state": "translated", + "value": "Phone" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Teléfono" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Téléphone" } } } }, - "Complete sign-in with your second factor" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Complete sign-in with your second factor" + "Phone Number": { + "comment": "Field label for phone number", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Telefonnummer" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Phone Number" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Número de teléfono" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Completa el inicio de sesión con tu segundo factor" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Numéro de téléphone" } } } }, - "ConfirmEmail" : { - "comment" : "Title of confirm email label.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Confirm Email" + "PlaceholderChosePassword": { + "comment": "Placeholder of secret input cell when user changes password.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort wählen" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Confirmar correo" + "en": { + "stringUnit": { + "state": "translated", + "value": "Choose password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Elegir contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Choisis un mot de passe" } } } }, - "Confirm Password" : { - "comment" : "Field label for confirming password", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Confirm Password" + "PlaceholderEnterEmail": { + "comment": "Placeholder of input cell when user changes name. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Gib deine E-Mail ein" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter your email" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa tu correo" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Confirmar contraseña" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis ton e-mail" } } } }, - "ConfirmPasswordInputLabel" : { - "comment" : "Input label for confirming password when signing up", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Confirm Password" + "PlaceholderEnterName": { + "comment": "Placeholder of input cell when user changes name.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Gib deinen Namen ein" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Confirmar contraseña" + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter your name" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa tu nombre" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis ton nom" } } } }, - "Copied to clipboard!" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Copied to clipboard!" + "PlaceholderEnterPassword": { + "comment": "Placeholder of secret input cell when user changes password.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Gib dein Passwort ein" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Enter your password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ingresa tu contraseña" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¡Copiado al portapapeles!" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Saisis ton mot de passe" } } } }, - "Delete" : { - "comment" : "Text of Delete action button.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Delete" + "PlaceholderNewPassword": { + "comment": "Placeholder of secret input cell when user confirms password.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Neues Passwort" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eliminar" + "en": { + "stringUnit": { + "state": "translated", + "value": "New password" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Nueva contraseña" + } + }, + "fr": { + "stringUnit": { + "state": "translated", + "value": "Nouveau mot de passe" } } } }, - "Delete Account" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Delete Account" + "PrivacyPolicy": { + "comment": "Text linked to a web page with the Privacy Policy content.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Datenschutzrichtlinie" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "Privacy Policy" + } + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Política de privacidad" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eliminar cuenta" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Politique de confidentialité" } } } }, - "Delete Account?" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Delete Account?" + "ProviderTitleFacebook": { + "comment": "Title of Facebook provider", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Facebook" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¿Eliminar cuenta?" + "en": { + "stringUnit": { + "state": "translated", + "value": "Facebook" } - } - } - }, - "DeleteAccountBody" : { - "comment" : "Alert message body shown to confirm account deletion action.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "This will erase all data associated with your account, and can't be undone You will need to sign in again to complete this action" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Facebook" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Esto borrará todos los datos asociados con tu cuenta y no se puede deshacer. Deberás iniciar sesión nuevamente para completar esta acción" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Facebook" } } } }, - "DeleteAccountConfirmationMessage" : { - "comment" : "Explanation message shown before deleting account.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "This will erase all data associated with your account, and can't be undone. Are you sure you want to delete your account?" + "ProviderTitleGoogle": { + "comment": "Title of Google provider", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Google" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Esto borrará todos los datos asociados con tu cuenta y no se puede deshacer. ¿Estás seguro de que deseas eliminar tu cuenta?" + "en": { + "stringUnit": { + "state": "translated", + "value": "Google" } - } - } - }, - "DeleteAccountConfirmationTitle" : { - "comment" : "Alert message title shown to confirm account deletion action.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Delete Account?" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Google" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¿Eliminar cuenta?" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Google" } } } }, - "DeleteAccountControllerTitle" : { - "comment" : "Title of Controller shown before deleting account", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Delete account" + "ProviderTitlePassword": { + "comment": "Title of Password/Email provider. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "E-Mail" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eliminar cuenta" + "en": { + "stringUnit": { + "state": "translated", + "value": "Email" } - } - } - }, - "Display Name" : { - "comment" : "Field label for display name", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Display Name" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Correo" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nombre para mostrar" + "fr": { + "stringUnit": { + "state": "translated", + "value": "E-mail" } } } }, - "Don't have an account yet?" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Don't have an account yet?" + "ProviderTitleTwitter": { + "comment": "Title of Twitter provider", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Twitter" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¿Aún no tienes una cuenta?" + "en": { + "stringUnit": { + "state": "translated", + "value": "Twitter" } - } - } - }, - "EditEmailTitle" : { - "comment" : "Controller title shown when editing account email. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Edit email" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Twitter" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Editar correo" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Twitter" } } } }, - "EditNameTitle" : { - "comment" : "Controller title shown when editing account name.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Edit name" + "ProviderUsedPreviouslyMessage": { + "comment": "Alert message to let user know what identity provider (second placeholder, ex. Google) was used previously for the email address (first placeholder).", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Du hast bereits %@ verwendet. Melde dich mit %@ an, um fortzufahren." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Editar nombre" + "en": { + "stringUnit": { + "state": "translated", + "value": "You've already used %@. Sign in with %@ to continue." } - } - } - }, - "EditPasswordAlertMessage" : { - "comment" : "Alert message shown when editing account password.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "To change password to your account, you will need to sign in again." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ya has usado %@. Inicia sesión con %@ para continuar." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Para cambiar la contraseña de tu cuenta, deberás iniciar sesión nuevamente." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Tu as déjà utilisé %@. Connecte-toi avec %@ pour continuer." } } } }, - "EditPasswordTitle" : { - "comment" : "Controller title shown when editing password to account.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Change password" + "ReauthenticateEditPasswordAlertMessage": { + "comment": "Alert message shown when re-authenticating before editing account password.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Um dein Passwort zu ändern, musst du zuerst dein aktuelles Passwort eingeben." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cambiar contraseña" + "en": { + "stringUnit": { + "state": "translated", + "value": "In order to change your password, you first need to enter your current password." } - } - } - }, - "Email" : { - "comment" : "Field label for email", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Email" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Para cambiar tu contraseña, primero debes ingresar tu contraseña actual." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Correo" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Pour modifier ton mot de passe, tu dois d'abord saisir ton mot de passe actuel." } } } }, - "EmailAlreadyInUseError" : { - "comment" : "Error message displayed when the email address is already in use. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "The email address is already in use by another account." + "Remove": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Entfernen" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "La dirección de correo ya está en uso por otra cuenta." + "en": { + "stringUnit": { + "state": "translated", + "value": "Remove" } - } - } - }, - "Enter code from app" : { - "comment" : "Prompt for entering code from authenticator app", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter code from app" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Eliminar" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa el código de la aplicación" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Retirer" } } } }, - "Enter display name for this authenticator" : { - "comment" : "Prompt for entering display name for authenticator", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter display name for this authenticator" + "Resend": { + "comment": "Resend button title.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Erneut senden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa el nombre para mostrar de este autenticador" + "en": { + "stringUnit": { + "state": "translated", + "value": "Resend" } - } - } - }, - "Enter display name for this device" : { - "comment" : "Prompt for entering display name for device", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter display name for this device" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Reenviar" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa el nombre para mostrar de este dispositivo" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Renvoyer" } } } }, - "Enter phone number" : { - "comment" : "Prompt for entering phone number", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter phone number" + "Resend Code": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Code erneut senden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa el número de teléfono" + "en": { + "stringUnit": { + "state": "translated", + "value": "Resend Code" } - } - } - }, - "EmailLinkSignInLabel" : { - "comment" : "Button label to push user to email link sign-in", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Prefer Email link sign-in?" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Reenviar código" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¿Prefieres iniciar sesión con enlace por correo?" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Renvoyer le code" } } } }, - "EmailLinkSignInTitle" : { - "comment" : "Sign in with email link View title", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign in with email link" + "Save": { + "comment": "Save button title.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Speichern" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión con enlace por correo" + "en": { + "stringUnit": { + "state": "translated", + "value": "Save" } - } - } - }, - "EmailsDontMatch" : { - "comment" : "Error message displayed when after re-authorization current user's email and re-authorized user's email doesn't match. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Emails don't match" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Guardar" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Los correos no coinciden" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Enregistrer" } } } }, - "EmailSentConfirmationMessage" : { - "comment" : "Message displayed after email is sent. The placeholder is the email address that the email is sent to.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "A sign-in email with additional instructions was sent to %@. Check your email to complete sign-in." + "Scan QR Code": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "QR-Code scannen" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Se envió un correo de inicio de sesión con instrucciones adicionales a %@. Revisa tu correo para completar el inicio de sesión." + "en": { + "stringUnit": { + "state": "translated", + "value": "Scan QR Code" } - } - } - }, - "Enrolled Methods" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enrolled Methods" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Escanear código QR" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Métodos registrados" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Scanner le code QR" } } } }, - "Enrolled: %@" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enrolled: %@" + "Scan with your authenticator app or tap to open directly": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Scanne mit deiner Authentifizierungs-App oder tippe, um direkt zu öffnen" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Registrado: %@" + "en": { + "stringUnit": { + "state": "translated", + "value": "Scan with your authenticator app or tap to open directly" } - } - } - }, - "Enter 6-digit code" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter 6-digit code" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Escanea con tu aplicación de autenticación o toca para abrir directamente" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa el código de 6 dígitos" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Scanne avec ton application d'authentification ou appuie pour ouvrir directement" } } } }, - "Enter the 6-digit code from your authenticator app" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter the 6-digit code from your authenticator app" + "Send": { + "comment": "Send button title.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Senden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa el código de 6 dígitos de tu aplicación de autenticación" + "en": { + "stringUnit": { + "state": "translated", + "value": "Send" } - } - } - }, - "Enter Verification Code" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter Verification Code" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviar" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa el código de verificación" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Envoyer" } } } }, - "Enter Your Phone Number" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter Your Phone Number" + "Send Code": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Code senden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa tu número de teléfono" + "en": { + "stringUnit": { + "state": "translated", + "value": "Send Code" } - } - } - }, - "EnterYourEmail" : { - "comment" : "Title for email entry screen, email text field placeholder. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter your email" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviar código" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa tu correo" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Envoyer le code" } } } }, - "EnterYourPassword" : { - "comment" : "Password text field placeholder.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter your password" + "SendEmailSignInLinkButtonLabel": { + "comment": "Button label for sending email sign-in link", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "E-Mail-Anmeldelink senden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa tu contraseña" + "en": { + "stringUnit": { + "state": "translated", + "value": "Send email sign-in link" } - } - } - }, - "Error" : { - "comment" : "Alert title Error.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Error" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviar enlace de inicio de sesión por correo" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Error" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Envoyer le lien de connexion par e-mail" } } } }, - "ExistingAccountTitle" : { - "comment" : "Title of an alert shown to an existing user coming back to the app.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "You already have an account" + "Set Up Two-Factor Authentication": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Zwei-Faktor-Authentifizierung einrichten" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ya tienes una cuenta" + "en": { + "stringUnit": { + "state": "translated", + "value": "Set Up Two-Factor Authentication" } - } - } - }, - "FirstAndLastName" : { - "comment" : "Name text field placeholder.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "First & last name" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Configurar autenticación de dos factores" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nombre y apellido" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Configurer l'authentification à deux facteurs" } } } }, - "ForgotPassword" : { - "comment" : "Button text for 'Forgot Password' action.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Send password recovery email" + "Set up two-factor authentication to add an extra layer of security to your account.": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Richte die Zwei-Faktor-Authentifizierung ein, um deinem Konto eine zusätzliche Sicherheitsebene hinzuzufügen." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviar correo de recuperación de contraseña" + "en": { + "stringUnit": { + "state": "translated", + "value": "Set up two-factor authentication to add an extra layer of security to your account." } - } - } - }, - "ForgotPasswordTitle" : { - "comment" : "Title of forgot password button.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trouble signing in?" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Configura la autenticación de dos factores para agregar una capa adicional de seguridad a tu cuenta." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¿Problemas para iniciar sesión?" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Configure l'authentification à deux facteurs pour ajouter une couche de sécurité supplémentaire à ton compte." } } } }, - "Get Started" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Get Started" + "Sign up": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Registrieren" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Comenzar" + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign up" } - } - } - }, - "InvalidEmailError" : { - "comment" : "Error message displayed when user enters an invalid email address. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "That email address isn't correct." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Registrarse" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Esa dirección de correo no es correcta." + "fr": { + "stringUnit": { + "state": "translated", + "value": "S'inscrire" } } } }, - "Invalid OAuth Provider" : { - "comment" : "Error message displayed when OAuth provider configuration is invalid.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Invalid OAuth Provider" + "SignedIn": { + "comment": "Title of successfully signed in label.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Angemeldet!" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Proveedor OAuth inválido" + "en": { + "stringUnit": { + "state": "translated", + "value": "Signed in!" } - } - } - }, - "InvalidPasswordError" : { - "comment" : "Error message displayed when user enters an empty password.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Password cannot be empty." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¡Sesión iniciada!" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "La contraseña no puede estar vacía." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Connecté !" } } } }, - "Login" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Login" + "SignInEmailSent": { + "comment": "Message displayed after the email of sign-in link is sent.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Anmelde-E-Mail gesendet" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión" + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign-in email Sent" } - } - } - }, - "Manage Two-Factor Authentication" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manage Two-Factor Authentication" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Correo de inicio de sesión enviado" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Administrar autenticación de dos factores" + "fr": { + "stringUnit": { + "state": "translated", + "value": "E-mail de connexion envoyé" } } } }, - "Manage your authentication methods" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manage your authentication methods" + "SignInTitle": { + "comment": "Title for sign in screen and sign in button.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Anmelden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Administra tus métodos de autenticación" + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign in" } - } - } - }, - "Manual Entry Key:" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Manual Entry Key:" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Clave de entrada manual:" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se connecter" } } } }, - "MFA is not enabled in the current configuration. Please contact your administrator." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "MFA is not enabled in the current configuration. Please contact your administrator." + "SignInTooManyTimesError": { + "comment": "Error message displayed after user trying to sign in too many times.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Du hast zu oft ein falsches Passwort eingegeben. Versuche es in ein paar Minuten erneut." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "MFA no está habilitado en la configuración actual. Por favor, contacta a tu administrador." + "en": { + "stringUnit": { + "state": "translated", + "value": "You've entered an incorrect password too many times. Try again in a few minutes." } - } - } - }, - "Multi-Factor Authentication Disabled" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Multi-Factor Authentication Disabled" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Has ingresado una contraseña incorrecta demasiadas veces. Intenta nuevamente en unos minutos." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Autenticación multifactor deshabilitada" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Tu as saisi un mot de passe incorrect trop de fois. Réessaie dans quelques minutes." } } } }, - "Name" : { - "comment" : "Label next to a name text field.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Name" + "Sign in with Apple": { + "comment": "Sign in with Apple button label.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Mit Apple anmelden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nombre" + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign in with Apple" } - } - } - }, - "Next" : { - "comment" : "Next button title.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Next" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión con Apple" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Siguiente" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se connecter avec Apple" } } } }, - "No Authentication Methods" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No Authentication Methods" + "Sign in with Facebook": { + "comment": "Sign in with Facebook button label.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Mit Facebook anmelden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sin métodos de autenticación" + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign in with Facebook" } - } - } - }, - "No Authentication Methods Available" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No Authentication Methods Available" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión con Facebook" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "No hay métodos de autenticación disponibles" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se connecter avec Facebook" } } } }, - "No MFA methods are configured as allowed. Please contact your administrator." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "No MFA methods are configured as allowed. Please contact your administrator." + "Sign in with Google": { + "comment": "Sign in with Google button label.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Mit Google anmelden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "No hay métodos MFA configurados como permitidos. Por favor, contacta a tu administrador." + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign in with Google" } - } - } - }, - "OK" : { - "comment" : "OK button title.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "OK" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión con Google" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Aceptar" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se connecter avec Google" } } } }, - "Password" : { - "comment" : "Field label for password", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Password" + "Sign in with Phone": { + "comment": "Sign in with Phone button label.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Mit Telefon anmelden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Contraseña" + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign in with Phone" } - } - } - }, - "PasswordRecoveryEmailSentMessage" : { - "comment" : "Message displayed when the email for password recovery has been sent.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Follow the instructions sent to %@ to recover your password." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión con teléfono" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sigue las instrucciones enviadas a %@ para recuperar tu contraseña." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se connecter avec un téléphone" } } } }, - "PasswordRecoveryEmailSentTitle" : { - "comment" : "Title of a message displayed when the email for password recovery has been sent. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Check your email" + "Sign in with X": { + "comment": "Sign in with X (Twitter) button label.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Mit X anmelden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Revisa tu correo" + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign in with X" } - } - } - }, - "PasswordRecoveryMessage" : { - "comment" : "Explanation on how the password of an account can be recovered. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Get instructions sent to this email that explain how to reset your password." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión con X" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Recibe instrucciones enviadas a este correo que explican cómo restablecer tu contraseña." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se connecter avec X" } } } }, - "PasswordRecoveryTitle" : { - "comment" : "Title for password recovery screen.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Recover password" + "SignInWithEmail": { + "comment": "Sign in with email button label. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Mit E-Mail anmelden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Recuperar contraseña" + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign in with email" } - } - } - }, - "PasswordVerificationMessage" : { - "comment" : "Message to explain to the user that password is needed for an account with this email address.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "You've already used %@ to sign in. Enter your password for that account." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión con correo" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ya has usado %@ para iniciar sesión. Ingresa tu contraseña para esa cuenta." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se connecter avec un e-mail" } } } }, - "Phone" : { - "comment" : "Field label for phone", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Phone" + "SignInWithProvider": { + "comment": "Sign in with provider button label.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Mit %@ anmelden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Teléfono" + "en": { + "stringUnit": { + "state": "translated", + "value": "Sign in with %@" } - } - } - }, - "Phone Number" : { - "comment" : "Field label for phone number", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Phone Number" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Iniciar sesión con %@" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Número de teléfono" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Se connecter avec %@" } } } }, - "PlaceholderChosePassword" : { - "comment" : "Placeholder of secret input cell when user changes password.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Choose password" + "SignUpTitle": { + "comment": "Title for sign up screen.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Konto erstellen" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Elegir contraseña" + "en": { + "stringUnit": { + "state": "translated", + "value": "Create account" } - } - } - }, - "PlaceholderEnterEmail" : { - "comment" : "Placeholder of input cell when user changes name. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter your email" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Crear cuenta" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa tu correo" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Créer un compte" } } } }, - "PlaceholderEnterName" : { - "comment" : "Placeholder of input cell when user changes name.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter your name" + "SignUpTooManyTimesError": { + "comment": "Error message displayed when many accounts have been created from same IP address.", + "extractionState": "migrated", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Zu viele Kontoanfragen kommen von deiner IP-Adresse. Versuche es in ein paar Minuten erneut." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa tu nombre" + "en": { + "stringUnit": { + "state": "translated", + "value": "Too many account requests are coming from your IP address. Try again in a few minutes." } - } - } - }, - "PlaceholderEnterPassword" : { - "comment" : "Placeholder of secret input cell when user changes password.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enter your password" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Demasiadas solicitudes de cuenta provienen de tu dirección IP. Intenta nuevamente en unos minutos." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ingresa tu contraseña" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Trop de demandes de compte proviennent de ton adresse IP. Réessaie dans quelques minutes." } } } }, - "PlaceholderNewPassword" : { - "comment" : "Placeholder of secret input cell when user confirms password.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "New password" + "SMS Authentication": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "SMS-Authentifizierung" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Nueva contraseña" + "en": { + "stringUnit": { + "state": "translated", + "value": "SMS Authentication" } - } - } - }, - "PrivacyPolicy" : { - "comment" : "Text linked to a web page with the Privacy Policy content.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Privacy Policy" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Autenticación por SMS" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Política de privacidad" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Authentification par SMS" } } } }, - "ProviderTitleFacebook" : { - "comment" : "Title of Facebook provider", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Facebook" + "SMS Verification": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "SMS-Verifizierung" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Facebook" + "en": { + "stringUnit": { + "state": "translated", + "value": "SMS Verification" } - } - } - }, - "ProviderTitleGoogle" : { - "comment" : "Title of Google provider", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Google" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Verificación por SMS" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Google" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Vérification par SMS" } } } }, - "ProviderTitlePassword" : { - "comment" : "Title of Password/Email provider. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Email" + "SMS: %@": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "SMS: %@" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Correo" + "en": { + "stringUnit": { + "state": "translated", + "value": "SMS: %@" } - } - } - }, - "ProviderTitleTwitter" : { - "comment" : "Title of Twitter provider", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Twitter" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "SMS: %@" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Twitter" + "fr": { + "stringUnit": { + "state": "translated", + "value": "SMS : %@" } } } }, - "ProviderUsedPreviouslyMessage" : { - "comment" : "Alert message to let user know what identity provider (second placeholder, ex. Google) was used previously for the email address (first placeholder).", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "You've already used %@. Sign in with %@ to continue." + "Tap to open in authenticator app": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Tippe, um in der Authentifizierungs-App zu öffnen" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ya has usado %@. Inicia sesión con %@ para continuar." + "en": { + "stringUnit": { + "state": "translated", + "value": "Tap to open in authenticator app" } - } - } - }, - "ReauthenticateEditPasswordAlertMessage" : { - "comment" : "Alert message shown when re-authenticating before editing account password.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "In order to change your password, you first need to enter your current password." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Toca para abrir en la aplicación de autenticación" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Para cambiar tu contraseña, primero debes ingresar tu contraseña actual." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Appuie pour ouvrir dans l'application d'authentification" } } } }, - "Remove" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Remove" + "TermsOfService": { + "comment": "Text linked to a web page with the Terms of Service content.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Nutzungsbedingungen" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Eliminar" + "en": { + "stringUnit": { + "state": "translated", + "value": "Terms of Service" } - } - } - }, - "Resend" : { - "comment" : "Resend button title.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Resend" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Términos de servicio" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Reenviar" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Conditions d'utilisation" } } } }, - "Resend Code" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Resend Code" + "TermsOfServiceMessage": { + "comment": "A message displayed when the first log in screen is displayed. The first placeholder is the terms of service agreement link, the second place holder is the privacy policy agreement link.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Indem du fortfährst, bestätigst du, dass du unsere %@ und %@ akzeptierst." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Reenviar código" + "en": { + "stringUnit": { + "state": "translated", + "value": "By continuing, you are indicating that you accept our %@ and %@." } - } - } - }, - "Save" : { - "comment" : "Save button title.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Save" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Al continuar, indicas que aceptas nuestros %@ y %@." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Guardar" + "fr": { + "stringUnit": { + "state": "translated", + "value": "En continuant, tu indiques que tu acceptes nos %@ et notre %@." } } } }, - "Scan QR Code" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Scan QR Code" + "This action cannot be undone. All your data will be permanently deleted. You may need to reauthenticate to complete this action.": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Diese Aktion kann nicht rückgängig gemacht werden. Alle deine Daten werden dauerhaft gelöscht. Du musst dich möglicherweise erneut authentifizieren, um diese Aktion abzuschließen." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Escanear código QR" + "en": { + "stringUnit": { + "state": "translated", + "value": "This action cannot be undone. All your data will be permanently deleted. You may need to reauthenticate to complete this action." } - } - } - }, - "Scan with your authenticator app or tap to open directly" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Scan with your authenticator app or tap to open directly" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Esta acción no se puede deshacer. Todos tus datos se eliminarán permanentemente. Es posible que debas volver a autenticarte para completar esta acción." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Escanea con tu aplicación de autenticación o toca para abrir directamente" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Cette action ne peut pas être annulée. Toutes tes données seront définitivement supprimées. Tu devras peut-être te réauthentifier pour effectuer cette action." } } } }, - "Send" : { - "comment" : "Send button title.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Send" + "TroubleGettingEmailMessage": { + "comment": "Alert message displayed when user having trouble getting email.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Versuche diese gängigen Lösungen: \n - Überprüfe, ob die E-Mail als Spam markiert oder gefiltert wurde.\n - Überprüfe deine Internetverbindung.\n - Überprüfe, ob du deine E-Mail nicht falsch geschrieben hast.\n - Überprüfe, ob dein Postfach voll ist oder andere Probleme mit den Postfacheinstellungen vorliegen.\n Wenn die obigen Schritte nicht funktioniert haben, kannst du die E-Mail erneut senden. Beachte, dass dadurch der Link in der älteren E-Mail deaktiviert wird." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviar" + "en": { + "stringUnit": { + "state": "translated", + "value": "Try these common fixes: \n - Check if the email was marked as spam or filtered.\n - Check your internet connection.\n - Check that you did not misspell your email.\n - Check that your inbox space is not running out or other inbox settings related issues.\n If the steps above didn't work, you can resend the email. Note that this will deactivate the link in the older email." } - } - } - }, - "Send Code" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Send Code" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Prueba estas soluciones comunes: \n - Verifica si el correo fue marcado como spam o filtrado.\n - Verifica tu conexión a internet.\n - Verifica que no hayas escrito mal tu correo.\n - Verifica que tu bandeja de entrada no esté llena u otros problemas relacionados con la configuración de la bandeja de entrada.\n Si los pasos anteriores no funcionaron, puedes reenviar el correo. Ten en cuenta que esto desactivará el enlace del correo anterior." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviar código" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Essaie ces solutions courantes :\n - Vérifie si l'e-mail a été marqué comme spam ou filtré.\n - Vérifie ta connexion Internet.\n - Vérifie que tu n'as pas mal orthographié ton e-mail.\n - Vérifie que l'espace de ta boîte de réception n'est pas saturé ou qu'il n'y a pas d'autres problèmes de paramètres de boîte de réception.\n Si les étapes ci-dessus n'ont pas fonctionné, tu peux renvoyer l'e-mail. Note que cela désactivera le lien dans l'ancien e-mail." } } } }, - "SendEmailSignInLinkButtonLabel" : { - "comment" : "Button label for sending email sign-in link", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Send email sign-in link" + "TroubleGettingEmailTitle": { + "comment": "Title used in trouble getting email alert view.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Probleme beim Empfang von E-Mails?" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviar enlace de inicio de sesión por correo" + "en": { + "stringUnit": { + "state": "translated", + "value": "Trouble getting emails?" } - } - } - }, - "Set Up Two-Factor Authentication" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Set Up Two-Factor Authentication" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¿Problemas para recibir correos?" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configurar autenticación de dos factores" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Problème pour recevoir les e-mails ?" } } } }, - "Set up two-factor authentication to add an extra layer of security to your account." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Set up two-factor authentication to add an extra layer of security to your account." + "Two-Factor Authentication": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Zwei-Faktor-Authentifizierung" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Configura la autenticación de dos factores para agregar una capa adicional de seguridad a tu cuenta." + "en": { + "stringUnit": { + "state": "translated", + "value": "Two-Factor Authentication" } - } - } - }, - "Sign up" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign up" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Autenticación de dos factores" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Registrarse" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Authentification à deux facteurs" } } } }, - "SignedIn" : { - "comment" : "Title of successfully signed in label.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Signed in!" + "Unable to generate QR Code": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "QR-Code kann nicht generiert werden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¡Sesión iniciada!" + "en": { + "stringUnit": { + "state": "translated", + "value": "Unable to generate QR Code" } - } - } - }, - "SignInEmailSent" : { - "comment" : "Message displayed after the email of sign-in link is sent.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign-in email Sent" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "No se puede generar el código QR" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Correo de inicio de sesión enviado" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Impossible de générer le code QR" } } } }, - "SignInTitle" : { - "comment" : "Title for sign in screen and sign in button.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign in" + "UnlinkAction": { + "comment": "Button title for unlinking account action.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Verknüpfung aufheben" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión" + "en": { + "stringUnit": { + "state": "translated", + "value": "Unlink" } - } - } - }, - "SignInTooManyTimesError" : { - "comment" : "Error message displayed after user trying to sign in too many times.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "You've entered an incorrect password too many times. Try again in a few minutes." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Desvincular" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Has ingresado una contraseña incorrecta demasiadas veces. Intenta nuevamente en unos minutos." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Délier" } } } }, - "Sign in with Apple" : { - "comment" : "Sign in with Apple button label.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign in with Apple" + "UnlinkConfirmationActionTitle": { + "comment": "Alert action title shown before unlinking action.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Kontoverknüpfung aufheben" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión con Apple" + "en": { + "stringUnit": { + "state": "translated", + "value": "Unlink account" } - } - } - }, - "Sign in with Facebook" : { - "comment" : "Sign in with Facebook button label.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign in with Facebook" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Desvincular cuenta" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión con Facebook" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Délier le compte" } } } }, - "Sign in with Google" : { - "comment" : "Sign in with Google button label.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign in with Google" + "UnlinkConfirmationMessage": { + "comment": "Alert message shown before unlinking action.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Du kannst dich nicht mehr mit deinem Konto anmelden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión con Google" + "en": { + "stringUnit": { + "state": "translated", + "value": "You will no longer be able to sign in using your account" } - } - } - }, - "Sign in with Phone" : { - "comment" : "Sign in with Phone button label.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign in with Phone" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Ya no podrás iniciar sesión usando tu cuenta" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión con teléfono" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Tu ne pourras plus te connecter en utilisant ton compte" } } } }, - "Sign in with X" : { - "comment" : "Sign in with X (Twitter) button label.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign in with X" + "UnlinkConfirmationTitle": { + "comment": "Alert title shown before unlinking action.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Kontoverknüpfung aufheben?" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión con X" + "en": { + "stringUnit": { + "state": "translated", + "value": "Unlink account?" } - } - } - }, - "SignInWithEmail" : { - "comment" : "Sign in with email button label. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign in with email" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¿Desvincular cuenta?" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión con correo" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Délier le compte ?" } } } }, - "SignInWithProvider" : { - "comment" : "Sign in with provider button label.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Sign in with %@" + "UnlinkTitle": { + "comment": "Controller title shown for unlinking account action.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Verknüpftes Konto" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Iniciar sesión con %@" + "en": { + "stringUnit": { + "state": "translated", + "value": "Linked account" } - } - } - }, - "SignUpTitle" : { - "comment" : "Title for sign up screen.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Create account" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Cuenta vinculada" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Crear cuenta" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Compte lié" } } } }, - "SignUpTooManyTimesError" : { - "comment" : "Error message displayed when many accounts have been created from same IP address.", - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Too many account requests are coming from your IP address. Try again in a few minutes." + "Update password": { + "comment": "Update password button label", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort aktualisieren" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Demasiadas solicitudes de cuenta provienen de tu dirección IP. Intenta nuevamente en unos minutos." + "en": { + "stringUnit": { + "state": "translated", + "value": "Update password" } - } - } - }, - "SMS Authentication" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "SMS Authentication" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Actualizar contraseña" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Autenticación por SMS" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Mettre à jour le mot de passe" } } } }, - "SMS Verification" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "SMS Verification" + "UpdateEmailAlertMessage": { + "comment": "Alert action message shown before updating email action. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Um die mit deinem Konto verknüpfte E-Mail-Adresse zu ändern, musst du dich erneut anmelden." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Verificación por SMS" + "en": { + "stringUnit": { + "state": "translated", + "value": "To change email address associated with your account, you will need to sign in again." } - } - } - }, - "SMS: %@" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "SMS: %@" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Para cambiar la dirección de correo asociada con tu cuenta, deberás iniciar sesión nuevamente." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "SMS: %@" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Pour modifier l'adresse e-mail associée à ton compte, tu devras te reconnecter." } } } }, - "Tap to open in authenticator app" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Tap to open in authenticator app" + "UpdateEmailVerificationAlertMessage": { + "comment": "Alert action message shown before confirmation of updating email action.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Um dein Passwort zu ändern, musst du zuerst dein aktuelles Passwort eingeben." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Toca para abrir en la aplicación de autenticación" + "en": { + "stringUnit": { + "state": "translated", + "value": "In order to change your password, you first need to enter your current password." } - } - } - }, - "TermsOfService" : { - "comment" : "Text linked to a web page with the Terms of Service content.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Terms of Service" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Para cambiar tu contraseña, primero debes ingresar tu contraseña actual." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Términos de servicio" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Pour modifier ton mot de passe, tu dois d'abord saisir ton mot de passe actuel." } } } }, - "TermsOfServiceMessage" : { - "comment" : "A message displayed when the first log in screen is displayed. The first placeholder is the terms of service agreement link, the second place holder is the privacy policy agreement link.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "By continuing, you are indicating that you accept our %@ and %@." + "Use an authenticator app like Google Authenticator or Authy to generate verification codes.": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Verwende eine Authentifizierungs-App wie Google Authenticator oder Authy, um Bestätigungscodes zu generieren." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Al continuar, indicas que aceptas nuestros %@ y %@." + "en": { + "stringUnit": { + "state": "translated", + "value": "Use an authenticator app like Google Authenticator or Authy to generate verification codes." } - } - } - }, - "This action cannot be undone. All your data will be permanently deleted. You may need to reauthenticate to complete this action." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "This action cannot be undone. All your data will be permanently deleted. You may need to reauthenticate to complete this action." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Usa una aplicación de autenticación como Google Authenticator o Authy para generar códigos de verificación." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Esta acción no se puede deshacer. Todos tus datos se eliminarán permanentemente. Es posible que debas volver a autenticarte para completar esta acción." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Utilise une application d'authentification comme Google Authenticator ou Authy pour générer des codes de vérification." } } } }, - "TroubleGettingEmailMessage" : { - "comment" : "Alert message displayed when user having trouble getting email.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Try these common fixes: \n - Check if the email was marked as spam or filtered.\n - Check your internet connection.\n - Check that you did not misspell your email.\n - Check that your inbox space is not running out or other inbox settings related issues.\n If the steps above didn't work, you can resend the email. Note that this will deactivate the link in the older email." + "UserNotFoundError": { + "comment": "Error message displayed when there's no account matching the email address. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "migrated", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Diese E-Mail-Adresse stimmt mit keinem vorhandenen Konto überein." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Prueba estas soluciones comunes: \n - Verifica si el correo fue marcado como spam o filtrado.\n - Verifica tu conexión a internet.\n - Verifica que no hayas escrito mal tu correo.\n - Verifica que tu bandeja de entrada no esté llena u otros problemas relacionados con la configuración de la bandeja de entrada.\n Si los pasos anteriores no funcionaron, puedes reenviar el correo. Ten en cuenta que esto desactivará el enlace del correo anterior." + "en": { + "stringUnit": { + "state": "translated", + "value": "That email address doesn't match an existing account." } - } - } - }, - "TroubleGettingEmailTitle" : { - "comment" : "Title used in trouble getting email alert view.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Trouble getting emails?" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Esa dirección de correo no coincide con una cuenta existente." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¿Problemas para recibir correos?" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Cette adresse e-mail ne correspond à aucun compte existant." } } } }, - "Two-Factor Authentication" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Two-Factor Authentication" + "Send a password recovery link to your email": { + "comment": "Field label for password recovery email", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort-Wiederherstellungslink an deine E-Mail senden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Autenticación de dos factores" + "en": { + "stringUnit": { + "state": "translated", + "value": "Send a password recovery link to your email" } - } - } - }, - "Unable to generate QR Code" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unable to generate QR Code" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviar un enlace de recuperación de contraseña a tu correo" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "No se puede generar el código QR" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Envoyer un lien de récupération de mot de passe à ton e-mail" } } } }, - "UnlinkAction" : { - "comment" : "Button title for unlinking account action.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unlink" + "Send a sign-in link to your email": { + "comment": "Field label for sign-in email link", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Anmeldelink an deine E-Mail senden" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Desvincular" + "en": { + "stringUnit": { + "state": "translated", + "value": "Send a sign-in link to your email" } - } - } - }, - "UnlinkConfirmationActionTitle" : { - "comment" : "Alert action title shown before unlinking action.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unlink account" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviar un enlace de inicio de sesión a tu correo" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Desvincular cuenta" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Envoyer un lien de connexion à ton e-mail" } } } }, - "UnlinkConfirmationMessage" : { - "comment" : "Alert message shown before unlinking action.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "You will no longer be able to sign in using your account" + "Verification Code": { + "comment": "Field label for verification code", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Bestätigungscode" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Ya no podrás iniciar sesión usando tu cuenta" + "en": { + "stringUnit": { + "state": "translated", + "value": "Verification Code" } - } - } - }, - "UnlinkConfirmationTitle" : { - "comment" : "Alert title shown before unlinking action.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Unlink account?" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Código de verificación" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¿Desvincular cuenta?" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Code de vérification" } } } }, - "UnlinkTitle" : { - "comment" : "Controller title shown for unlinking account action.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Linked account" + "Verify email address?": { + "comment": "Label for sending email verification to user.", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "E-Mail-Adresse verifizieren?" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Cuenta vinculada" + "en": { + "stringUnit": { + "state": "translated", + "value": "Verify email address?" } - } - } - }, - "Update password" : { - "comment" : "Update password button label", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Update password" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "¿Verificar dirección de correo?" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Actualizar contraseña" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Vérifier l'adresse e-mail ?" } } } }, - "UpdateEmailAlertMessage" : { - "comment" : "Alert action message shown before updating email action. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "To change email address associated with your account, you will need to sign in again." + "VerifyItsYou": { + "comment": "Alert message title show for re-authorization.", + "extractionState": "manual", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Bestätige, dass du es bist" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Para cambiar la dirección de correo asociada con tu cuenta, deberás iniciar sesión nuevamente." + "en": { + "stringUnit": { + "state": "translated", + "value": "Verify it's you" } - } - } - }, - "UpdateEmailVerificationAlertMessage" : { - "comment" : "Alert action message shown before confirmation of updating email action.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "In order to change your password, you first need to enter your current password." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Verifica que eres tú" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Para cambiar tu contraseña, primero debes ingresar tu contraseña actual." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Vérifie que c'est toi" } } } }, - "Use an authenticator app like Google Authenticator or Authy to generate verification codes." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Use an authenticator app like Google Authenticator or Authy to generate verification codes." + "We sent a code to %@": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Wir haben einen Code an %@ gesendet" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Usa una aplicación de autenticación como Google Authenticator o Authy para generar códigos de verificación." + "en": { + "stringUnit": { + "state": "translated", + "value": "We sent a code to %@" } - } - } - }, - "UserNotFoundError" : { - "comment" : "Error message displayed when there's no account matching the email address. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "That email address doesn't match an existing account." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviamos un código a %@" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Esa dirección de correo no coincide con una cuenta existente." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Nous avons envoyé un code à %@" } } } }, - "Send a password recovery link to your email" : { - "comment" : "Field label for password recovery email", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Send a password recovery link to your email" + "We'll send a code to ••••••%@": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Wir senden einen Code an ••••••%@" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviar un enlace de recuperación de contraseña a tu correo" + "en": { + "stringUnit": { + "state": "translated", + "value": "We'll send a code to ••••••%@" } - } - } - }, - "Send a sign-in link to your email" : { - "comment" : "Field label for sign-in email link", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Send a sign-in link to your email" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviaremos un código a ••••••%@" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviar un enlace de inicio de sesión a tu correo" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Nous enverrons un code à ••••••%@" } } } }, - "Verification Code" : { - "comment" : "Field label for verification code", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Verification Code" + "We'll send a verification code to this number": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Wir senden einen Bestätigungscode an diese Nummer" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Código de verificación" + "en": { + "stringUnit": { + "state": "translated", + "value": "We'll send a verification code to this number" } - } - } - }, - "Verify email address?" : { - "comment" : "Label for sending email verification to user.", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Verify email address?" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviaremos un código de verificación a este número" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "¿Verificar dirección de correo?" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Nous enverrons un code de vérification à ce numéro" } } } }, - "VerifyItsYou" : { - "comment" : "Alert message title show for re-authorization.", - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Verify it's you" + "We'll send a verification code to your phone": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Wir senden einen Bestätigungscode an dein Telefon" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Verifica que eres tú" + "en": { + "stringUnit": { + "state": "translated", + "value": "We'll send a verification code to your phone" } - } - } - }, - "We sent a code to %@" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "We sent a code to %@" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviaremos un código de verificación a tu teléfono" } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviamos un código a %@" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Nous enverrons un code de vérification à ton téléphone" } } } }, - "We'll send a code to ••••••%@" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "We'll send a code to ••••••%@" + "We'll send a verification code to your phone number each time you sign in.": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Wir senden jedes Mal einen Bestätigungscode an deine Telefonnummer, wenn du dich anmeldest." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviaremos un código a ••••••%@" + "en": { + "stringUnit": { + "state": "translated", + "value": "We'll send a verification code to your phone number each time you sign in." } - } - } - }, - "We'll send a verification code to this number" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "We'll send a verification code to this number" + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "Enviaremos un código de verificación a tu número de teléfono cada vez que inicies sesión." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviaremos un código de verificación a este número" + "fr": { + "stringUnit": { + "state": "translated", + "value": "Nous enverrons un code de vérification à ton numéro de téléphone chaque fois que tu te connectes." } } } }, - "We'll send a verification code to your phone" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "We'll send a verification code to your phone" + "WeakPasswordError": { + "comment": "Error message displayed when the password is too weak.", + "extractionState": "migrated", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Passwort muss mindestens 6 Zeichen lang sein." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviaremos un código de verificación a tu teléfono" + "en": { + "stringUnit": { + "state": "translated", + "value": "Password must be at least 6 characters long." } - } - } - }, - "We'll send a verification code to your phone number each time you sign in." : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "We'll send a verification code to your phone number each time you sign in." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "La contraseña debe tener al menos 6 caracteres." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "Enviaremos un código de verificación a tu número de teléfono cada vez que inicies sesión." + "fr": { + "stringUnit": { + "state": "translated", + "value": "Le mot de passe doit contenir au moins 6 caractères." } } } }, - "WeakPasswordError" : { - "comment" : "Error message displayed when the password is too weak.", - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Password must be at least 6 characters long." + "WrongPasswordError": { + "comment": "Error message displayed when the email and password don't match. Use short/abbreviated translation for 'email' which is less than 15 chars.", + "extractionState": "migrated", + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "Die E-Mail und das Passwort, die du eingegeben hast, stimmen nicht überein." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "La contraseña debe tener al menos 6 caracteres." + "en": { + "stringUnit": { + "state": "translated", + "value": "The email and password you entered don't match." } - } - } - }, - "WrongPasswordError" : { - "comment" : "Error message displayed when the email and password don't match. Use short/abbreviated translation for 'email' which is less than 15 chars.", - "extractionState" : "migrated", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "The email and password you entered don't match." + }, + "es": { + "stringUnit": { + "state": "translated", + "value": "El correo y la contraseña que ingresaste no coinciden." } }, - "es" : { - "stringUnit" : { - "state" : "translated", - "value" : "El correo y la contraseña que ingresaste no coinciden." + "fr": { + "stringUnit": { + "state": "translated", + "value": "L'e-mail et le mot de passe que tu as saisis ne correspondent pas." } } } } }, - "version" : "1.0" + "version": "1.0" } \ No newline at end of file diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift index affdbb002d..0c80f453c4 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift @@ -19,14 +19,35 @@ let kKeyNotFound = "Key not found" public class StringUtils { let bundle: Bundle - init(bundle: Bundle) { + let locale: Locale? + + init(bundle: Bundle, locale: Locale? = nil) { self.bundle = bundle + self.locale = locale } public func localizedString(for key: String) -> String { - let keyLocale = String.LocalizationValue(key) - let value = String(localized: keyLocale, bundle: bundle) - return value + // If a specific locale is set, use NSLocalizedString with the locale's language code + if let locale { + let languageCode = locale.language.languageCode?.identifier ?? locale.identifier + + // Get the localized string from the bundle for the specific language + if let path = bundle.path(forResource: languageCode, ofType: "lproj"), + let localizedBundle = Bundle(path: path) { + let localizedString = localizedBundle.localizedString(forKey: key, value: nil, table: "Localizable") + // If we got a localized string (not the key back), return it + if localizedString != key { + return localizedString + } + } + + // Fallback to default bundle if language-specific bundle not found + return bundle.localizedString(forKey: key, value: nil, table: "Localizable") + } else { + let keyLocale = String.LocalizationValue(key) + let value = String(localized: keyLocale, bundle: bundle) + return value + } } public func localizedErrorMessage(for error: Error) -> String { diff --git a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift index ee17bf6782..4c3e01742e 100644 --- a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift +++ b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift @@ -39,7 +39,7 @@ struct ContentView: View { actionCodeSettings.linkDomain = "flutterfire-e2e-tests.firebaseapp.com" actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!) let configuration = AuthConfiguration( - logo: .icLineLogo, + locale: Locale(identifier: "es"), tosUrl: URL(string: "https://example.com/tos"), privacyPolicyUrl: URL(string: "https://example.com/privacy"), emailLinkSignInActionCodeSettings: actionCodeSettings, diff --git a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/Info.plist b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/Info.plist index bea005ea42..ef9ba13278 100644 --- a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/Info.plist +++ b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/Info.plist @@ -45,6 +45,8 @@ en es + de + fr From 1b7d17aa1464ed44a3a77a08f35ae449e8065ed7 Mon Sep 17 00:00:00 2001 From: Ademola Fadumo Date: Wed, 5 Nov 2025 14:18:23 +0100 Subject: [PATCH 3/7] fix: remove setVerificationCode for phone auth --- .../Sources/Services/AuthConfiguration.swift | 6 +-- .../Sources/Services/AuthService.swift | 4 +- .../Sources/Utils/StringUtils.swift | 33 +++++---------- .../Sources/Views/EnterPhoneNumberView.swift | 8 ++-- .../Views/EnterVerificationCodeView.swift | 36 ++++++---------- .../Services/PhoneAuthProviderAuthUI.swift | 19 +++------ firebase-debug.log | 41 +++++++++++++++++++ .../xcschemes/FirebaseSwiftUIExample.xcscheme | 2 +- .../App/ContentView.swift | 6 ++- .../App/FirebaseSwiftUIExampleApp.swift | 1 - .../FirebaseSwiftUIExample/Info.plist | 14 +++---- 11 files changed, 89 insertions(+), 81 deletions(-) create mode 100644 firebase-debug.log diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift index 3c45c49849..3eb6f24368 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift @@ -22,7 +22,7 @@ public struct AuthConfiguration { public let interactiveDismissEnabled: Bool public let shouldAutoUpgradeAnonymousUsers: Bool public let customStringsBundle: Bundle? - public let locale: Locale? + public let languageCode: String? public let tosUrl: URL? public let privacyPolicyUrl: URL? public let emailLinkSignInActionCodeSettings: ActionCodeSettings? @@ -40,7 +40,7 @@ public struct AuthConfiguration { interactiveDismissEnabled: Bool = true, shouldAutoUpgradeAnonymousUsers: Bool = false, customStringsBundle: Bundle? = nil, - locale: Locale? = nil, + languageCode: String? = nil, tosUrl: URL? = nil, privacyPolicyUrl: URL? = nil, emailLinkSignInActionCodeSettings: ActionCodeSettings? = nil, @@ -54,7 +54,7 @@ public struct AuthConfiguration { self.interactiveDismissEnabled = interactiveDismissEnabled self.shouldAutoUpgradeAnonymousUsers = shouldAutoUpgradeAnonymousUsers self.customStringsBundle = customStringsBundle - self.locale = locale + self.languageCode = languageCode self.tosUrl = tosUrl self.privacyPolicyUrl = privacyPolicyUrl self.emailLinkSignInActionCodeSettings = emailLinkSignInActionCodeSettings diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift index 999654a72e..b8c6e87486 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift @@ -29,7 +29,7 @@ public protocol AuthProviderUI { public protocol PhoneAuthProviderSwift: AuthProviderSwift { @MainActor func verifyPhoneNumber(phoneNumber: String) async throws -> String - func setVerificationCode(verificationID: String, code: String) + @MainActor func createAuthCredential(verificationId: String, verificationCode: String) async throws -> AuthCredential } public enum AuthenticationState { @@ -109,7 +109,7 @@ public final class AuthService { public init(configuration: AuthConfiguration = AuthConfiguration(), auth: Auth = Auth.auth()) { self.auth = auth self.configuration = configuration - string = StringUtils(bundle: configuration.customStringsBundle ?? Bundle.module, locale: configuration.locale) + string = StringUtils(bundle: configuration.customStringsBundle ?? Bundle.module, languageCode: configuration.languageCode) listenerManager = AuthListenerManager(auth: auth, authEnvironment: self) FirebaseApp.registerLibrary("firebase-ui-ios", withVersion: FirebaseAuthSwiftUIVersion.version) } diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift index 0c80f453c4..01db61caa1 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Utils/StringUtils.swift @@ -19,35 +19,22 @@ let kKeyNotFound = "Key not found" public class StringUtils { let bundle: Bundle - let locale: Locale? + let languageCode: String? - init(bundle: Bundle, locale: Locale? = nil) { + init(bundle: Bundle, languageCode: String? = nil) { self.bundle = bundle - self.locale = locale + self.languageCode = languageCode } public func localizedString(for key: String) -> String { - // If a specific locale is set, use NSLocalizedString with the locale's language code - if let locale { - let languageCode = locale.language.languageCode?.identifier ?? locale.identifier - - // Get the localized string from the bundle for the specific language - if let path = bundle.path(forResource: languageCode, ofType: "lproj"), - let localizedBundle = Bundle(path: path) { - let localizedString = localizedBundle.localizedString(forKey: key, value: nil, table: "Localizable") - // If we got a localized string (not the key back), return it - if localizedString != key { - return localizedString - } - } - - // Fallback to default bundle if language-specific bundle not found - return bundle.localizedString(forKey: key, value: nil, table: "Localizable") - } else { - let keyLocale = String.LocalizationValue(key) - let value = String(localized: keyLocale, bundle: bundle) - return value + // If a specific language code is set, load strings from that language bundle + if let languageCode, let path = bundle.path(forResource: languageCode, ofType: "lproj"), let localizedBundle = Bundle(path: path) { + return localizedBundle.localizedString(forKey: key, value: nil, table: "Localizable") } + + // Use default localization + let keyLocale = String.LocalizationValue(key) + return String(localized: keyLocale, bundle: bundle) } public func localizedErrorMessage(for error: Error) -> String { diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift index 19589bacaa..88b393e941 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift @@ -99,13 +99,13 @@ struct EnterPhoneNumberView: View { return "mock-verification-id" } - func setVerificationCode(verificationID _: String, code _: String) { - // Mock implementation - } - func createAuthCredential() async throws -> AuthCredential { fatalError("Not implemented in preview") } + + func createAuthCredential(verificationId: String, verificationCode: String) async throws -> AuthCredential { + fatalError("Not implemented in preview") + } } return EnterPhoneNumberView(phoneProvider: MockPhoneProvider()) diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterVerificationCodeView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterVerificationCodeView.swift index 0356d3120c..21fc113b2a 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterVerificationCodeView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterVerificationCodeView.swift @@ -20,16 +20,14 @@ import SwiftUI @MainActor struct EnterVerificationCodeView: View { @Environment(AuthService.self) private var authService - @Environment(\.dismiss) private var dismiss @State private var verificationCode: String = "" - @State private var currentError: AlertError? = nil - @State private var isProcessing: Bool = false let verificationID: String let fullPhoneNumber: String let phoneProvider: PhoneAuthProviderSwift var body: some View { + @Bindable var authService = authService VStack(spacing: 32) { VStack(spacing: 16) { VStack(spacing: 8) { @@ -50,31 +48,21 @@ struct EnterVerificationCodeView: View { .padding(.bottom) .frame(maxWidth: .infinity, alignment: .leading) - VerificationCodeInputField( - code: $verificationCode, - isError: currentError != nil, - errorMessage: currentError?.message - ) + VerificationCodeInputField(code: $verificationCode) Button(action: { Task { - isProcessing = true do { - phoneProvider.setVerificationCode( - verificationID: verificationID, - code: verificationCode - ) - let credential = try await phoneProvider.createAuthCredential() + let credential = try await phoneProvider.createAuthCredential(verificationId: verificationID, verificationCode: verificationCode) _ = try await authService.signIn(credentials: credential) - dismiss() + authService.navigator.clear() } catch { - currentError = AlertError(message: error.localizedDescription) - isProcessing = false + } } }) { - if isProcessing { + if authService.authenticationState == .authenticating { ProgressView() .frame(height: 32) .frame(maxWidth: .infinity) @@ -85,7 +73,7 @@ struct EnterVerificationCodeView: View { } } .buttonStyle(.borderedProminent) - .disabled(isProcessing || verificationCode.count != 6) + .disabled(authService.authenticationState == .authenticating || verificationCode.count != 6) } Spacer() @@ -93,7 +81,7 @@ struct EnterVerificationCodeView: View { .navigationTitle(authService.string.enterVerificationCodeTitle) .navigationBarTitleDisplayMode(.inline) .padding(.horizontal) - .errorAlert(error: $currentError, okButtonLabel: authService.string.okButtonLabel) + .errorAlert(error: $authService.currentError, okButtonLabel: authService.string.okButtonLabel) } } @@ -107,13 +95,13 @@ struct EnterVerificationCodeView: View { return "mock-verification-id" } - func setVerificationCode(verificationID _: String, code _: String) { - // Mock implementation - } - func createAuthCredential() async throws -> AuthCredential { fatalError("Not implemented in preview") } + + func createAuthCredential(verificationId: String, verificationCode: String) async throws -> AuthCredential { + fatalError("Not implemented in preview") + } } return NavigationStack { diff --git a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Services/PhoneAuthProviderAuthUI.swift b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Services/PhoneAuthProviderAuthUI.swift index 2e4e66c8f3..c2e3aa2dd3 100644 --- a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Services/PhoneAuthProviderAuthUI.swift +++ b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Services/PhoneAuthProviderAuthUI.swift @@ -19,9 +19,6 @@ import SwiftUI public typealias VerificationID = String public class PhoneProviderSwift: PhoneAuthProviderSwift { - private var verificationID: String? - private var verificationCode: String? - public init() {} @MainActor public func verifyPhoneNumber(phoneNumber: String) async throws -> VerificationID { @@ -37,19 +34,13 @@ public class PhoneProviderSwift: PhoneAuthProviderSwift { } } - public func setVerificationCode(verificationID: String, code: String) { - self.verificationID = verificationID - verificationCode = code - } - @MainActor public func createAuthCredential() async throws -> AuthCredential { - guard let verificationID = verificationID, - let verificationCode = verificationCode else { - throw AuthServiceError.providerAuthenticationFailed("Verification ID or code not set") - } - + fatalError("Not implemented") + } + + @MainActor public func createAuthCredential(verificationId: String, verificationCode: String) async throws -> AuthCredential { return PhoneAuthProvider.provider() - .credential(withVerificationID: verificationID, verificationCode: verificationCode) + .credential(withVerificationID: verificationId, verificationCode: verificationCode) } } diff --git a/firebase-debug.log b/firebase-debug.log new file mode 100644 index 0000000000..6c103f1ecb --- /dev/null +++ b/firebase-debug.log @@ -0,0 +1,41 @@ +[debug] [2025-11-05T12:00:41.564Z] ---------------------------------------------------------------------- +[debug] [2025-11-05T12:00:41.565Z] Command: /opt/homebrew/Cellar/node/25.1.0_1/bin/node /Users/ademolafadumo/.npm-global/bin/firebase emulators:start --only auth +[debug] [2025-11-05T12:00:41.565Z] CLI Version: 14.23.0 +[debug] [2025-11-05T12:00:41.565Z] Platform: darwin +[debug] [2025-11-05T12:00:41.565Z] Node Version: v25.1.0 +[debug] [2025-11-05T12:00:41.566Z] Time: Wed Nov 05 2025 13:00:41 GMT+0100 (West Africa Standard Time) +[debug] [2025-11-05T12:00:41.566Z] ---------------------------------------------------------------------- +[debug] +[debug] [2025-11-05T12:00:41.581Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] +[debug] [2025-11-05T12:00:41.581Z] > authorizing via signed-in user (demolafadumo@gmail.com) +[warn] ⚠ Could not find config (firebase.json) so using defaults. +[info] i emulators: Starting emulators: auth {"metadata":{"emulator":{"name":"hub"},"message":"Starting emulators: auth"}} +[info] i emulators: Detected demo project ID "demo-no-project", emulated services will use a demo configuration and attempts to access non-emulated services for this project will fail. {"metadata":{"emulator":{"name":"hub"},"message":"Detected demo project ID \"demo-no-project\", emulated services will use a demo configuration and attempts to access non-emulated services for this project will fail."}} +[debug] [2025-11-05T12:00:41.851Z] [logging] Logging Emulator only supports listening on one address (127.0.0.1). Not listening on ::1 +[debug] [2025-11-05T12:00:41.851Z] [auth] Authentication Emulator only supports listening on one address (127.0.0.1). Not listening on ::1 +[debug] [2025-11-05T12:00:41.851Z] assigned listening specs for emulators {"user":{"hub":[{"address":"127.0.0.1","family":"IPv4","port":4400},{"address":"::1","family":"IPv6","port":4400}],"ui":[{"address":"127.0.0.1","family":"IPv4","port":4000},{"address":"::1","family":"IPv6","port":4000}],"logging":[{"address":"127.0.0.1","family":"IPv4","port":4500}],"auth":[{"address":"127.0.0.1","family":"IPv4","port":9099}]},"metadata":{"message":"assigned listening specs for emulators"}} +[debug] [2025-11-05T12:00:41.854Z] Emulator locator file path: /var/folders/pw/cv4hgr3x2fbcrxbj9s2d60dw0000gn/T/hub-demo-no-project.json +[debug] [2025-11-05T12:00:41.854Z] [hub] writing locator at /var/folders/pw/cv4hgr3x2fbcrxbj9s2d60dw0000gn/T/hub-demo-no-project.json +[debug] [2025-11-05T12:00:44.618Z] Could not find VSCode notification endpoint: FetchError: request to http://localhost:40001/vscode/notify failed, reason: . If you are not running the Firebase Data Connect VSCode extension, this is expected and not an issue. +[info] +┌─────────────────────────────────────────────────────────────┐ +│ ✔ All emulators ready! It is now safe to connect your app. │ +│ i View Emulator UI at http://127.0.0.1:4000/ │ +└─────────────────────────────────────────────────────────────┘ + +┌────────────────┬────────────────┬────────────────────────────┐ +│ Emulator │ Host:Port │ View in Emulator UI │ +├────────────────┼────────────────┼────────────────────────────┤ +│ Authentication │ 127.0.0.1:9099 │ http://127.0.0.1:4000/auth │ +└────────────────┴────────────────┴────────────────────────────┘ + Emulator Hub host: 127.0.0.1 port: 4400 + Other reserved ports: 4500 + +Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files. + +[info] i To verify the phone number +2348145495544, use the code 544557. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 544557."}} +[info] i To verify the phone number +2348145495544, use the code 227440. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 227440."}} +[info] i To verify the phone number +2348145495544, use the code 777655. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 777655."}} +[info] i To verify the phone number +2348145495544, use the code 309002. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 309002."}} +[info] i To verify the phone number +2348145495544, use the code 227291. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 227291."}} +[info] i To verify the phone number +2348145495544, use the code 419134. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 419134."}} diff --git a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/xcshareddata/xcschemes/FirebaseSwiftUIExample.xcscheme b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/xcshareddata/xcschemes/FirebaseSwiftUIExample.xcscheme index bbe3e1cad5..30faacec20 100644 --- a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/xcshareddata/xcschemes/FirebaseSwiftUIExample.xcscheme +++ b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/xcshareddata/xcschemes/FirebaseSwiftUIExample.xcscheme @@ -31,7 +31,7 @@ shouldAutocreateTestPlan = "YES"> + CFBundleLocalizations + + en + es + de + fr + CFBundleURLTypes @@ -41,12 +48,5 @@ fetch remote-notification - CFBundleLocalizations - - en - es - de - fr - From 45d5a3ccf35464c5fce1f3597a680dae4a546011 Mon Sep 17 00:00:00 2001 From: Ademola Fadumo Date: Wed, 5 Nov 2025 14:42:34 +0100 Subject: [PATCH 4/7] fix: phone auth uses navigator --- .../Sources/Views/PhoneAuthButtonView.swift | 4 +--- firebase-debug.log | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift index 446029ea1b..5f24d7cf35 100644 --- a/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift +++ b/FirebaseSwiftUI/FirebasePhoneAuthSwiftUI/Sources/Views/PhoneAuthButtonView.swift @@ -34,9 +34,7 @@ extension PhoneAuthButtonView: View { style: .phone, accessibilityId: "sign-in-with-phone-button" ) { - Task { - try? await authService.signIn(phoneProvider) - } + authService.navigator.push(.enterPhoneNumber) } } } diff --git a/firebase-debug.log b/firebase-debug.log index 6c103f1ecb..27e325329f 100644 --- a/firebase-debug.log +++ b/firebase-debug.log @@ -39,3 +39,5 @@ Issues? Report them at https://github.com/firebase/firebase-tools/issues and att [info] i To verify the phone number +2348145495544, use the code 309002. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 309002."}} [info] i To verify the phone number +2348145495544, use the code 227291. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 227291."}} [info] i To verify the phone number +2348145495544, use the code 419134. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 419134."}} +[warn] ⚠ Received a signed JWT. Auth Emulator does not validate JWTs and IS NOT SECURE {"metadata":{"emulator":{"name":"auth"},"message":"Received a signed JWT. Auth Emulator does not validate JWTs and IS NOT SECURE"}} +[warn] ⚠ Received a signed JWT. Auth Emulator does not validate JWTs and IS NOT SECURE {"metadata":{"emulator":{"name":"auth"},"message":"Received a signed JWT. Auth Emulator does not validate JWTs and IS NOT SECURE"}} From dc4bc9d67a2b2f4ef150ebd9c6e7c90830f0c673 Mon Sep 17 00:00:00 2001 From: Ademola Fadumo Date: Wed, 5 Nov 2025 15:02:46 +0100 Subject: [PATCH 5/7] refactor: remove redundant ui code from phone auth related views --- .../Sources/Views/EnterPhoneNumberView.swift | 14 ++---- firebase-debug.log | 43 ------------------- 2 files changed, 4 insertions(+), 53 deletions(-) delete mode 100644 firebase-debug.log diff --git a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift index 0340d36848..0abf0c057a 100644 --- a/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift +++ b/FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EnterPhoneNumberView.swift @@ -21,8 +21,6 @@ struct EnterPhoneNumberView: View { @Environment(AuthService.self) private var authService @State private var phoneNumber: String = "" @State private var selectedCountry: CountryData = .default - @State private var currentError: AlertError? = nil - @State private var isProcessing: Bool = false var body: some View { VStack(spacing: 16) { @@ -43,13 +41,12 @@ struct EnterPhoneNumberView: View { ) { CountrySelector( selectedCountry: $selectedCountry, - enabled: !isProcessing + enabled: !(authService.authenticationState == .authenticating) ) } Button(action: { Task { - isProcessing = true do { guard let provider = authService.currentPhoneProvider else { fatalError("No phone provider found") @@ -60,14 +57,11 @@ struct EnterPhoneNumberView: View { verificationID: id, fullPhoneNumber: fullPhoneNumber )) - currentError = nil } catch { - currentError = AlertError(message: error.localizedDescription) } - isProcessing = false } }) { - if isProcessing { + if authService.authenticationState == .authenticating { ProgressView() .frame(height: 32) .frame(maxWidth: .infinity) @@ -78,14 +72,14 @@ struct EnterPhoneNumberView: View { } } .buttonStyle(.borderedProminent) - .disabled(isProcessing || phoneNumber.isEmpty) + .disabled(authService.authenticationState == .authenticating || phoneNumber.isEmpty) .padding(.top, 8) Spacer() } .navigationTitle(authService.string.phoneSignInTitle) .padding(.horizontal) - .errorAlert(error: $currentError, okButtonLabel: authService.string.okButtonLabel) + .errorAlert(error: authService.currentError, okButtonLabel: authService.string.okButtonLabel) } } diff --git a/firebase-debug.log b/firebase-debug.log deleted file mode 100644 index 27e325329f..0000000000 --- a/firebase-debug.log +++ /dev/null @@ -1,43 +0,0 @@ -[debug] [2025-11-05T12:00:41.564Z] ---------------------------------------------------------------------- -[debug] [2025-11-05T12:00:41.565Z] Command: /opt/homebrew/Cellar/node/25.1.0_1/bin/node /Users/ademolafadumo/.npm-global/bin/firebase emulators:start --only auth -[debug] [2025-11-05T12:00:41.565Z] CLI Version: 14.23.0 -[debug] [2025-11-05T12:00:41.565Z] Platform: darwin -[debug] [2025-11-05T12:00:41.565Z] Node Version: v25.1.0 -[debug] [2025-11-05T12:00:41.566Z] Time: Wed Nov 05 2025 13:00:41 GMT+0100 (West Africa Standard Time) -[debug] [2025-11-05T12:00:41.566Z] ---------------------------------------------------------------------- -[debug] -[debug] [2025-11-05T12:00:41.581Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"] -[debug] [2025-11-05T12:00:41.581Z] > authorizing via signed-in user (demolafadumo@gmail.com) -[warn] ⚠ Could not find config (firebase.json) so using defaults. -[info] i emulators: Starting emulators: auth {"metadata":{"emulator":{"name":"hub"},"message":"Starting emulators: auth"}} -[info] i emulators: Detected demo project ID "demo-no-project", emulated services will use a demo configuration and attempts to access non-emulated services for this project will fail. {"metadata":{"emulator":{"name":"hub"},"message":"Detected demo project ID \"demo-no-project\", emulated services will use a demo configuration and attempts to access non-emulated services for this project will fail."}} -[debug] [2025-11-05T12:00:41.851Z] [logging] Logging Emulator only supports listening on one address (127.0.0.1). Not listening on ::1 -[debug] [2025-11-05T12:00:41.851Z] [auth] Authentication Emulator only supports listening on one address (127.0.0.1). Not listening on ::1 -[debug] [2025-11-05T12:00:41.851Z] assigned listening specs for emulators {"user":{"hub":[{"address":"127.0.0.1","family":"IPv4","port":4400},{"address":"::1","family":"IPv6","port":4400}],"ui":[{"address":"127.0.0.1","family":"IPv4","port":4000},{"address":"::1","family":"IPv6","port":4000}],"logging":[{"address":"127.0.0.1","family":"IPv4","port":4500}],"auth":[{"address":"127.0.0.1","family":"IPv4","port":9099}]},"metadata":{"message":"assigned listening specs for emulators"}} -[debug] [2025-11-05T12:00:41.854Z] Emulator locator file path: /var/folders/pw/cv4hgr3x2fbcrxbj9s2d60dw0000gn/T/hub-demo-no-project.json -[debug] [2025-11-05T12:00:41.854Z] [hub] writing locator at /var/folders/pw/cv4hgr3x2fbcrxbj9s2d60dw0000gn/T/hub-demo-no-project.json -[debug] [2025-11-05T12:00:44.618Z] Could not find VSCode notification endpoint: FetchError: request to http://localhost:40001/vscode/notify failed, reason: . If you are not running the Firebase Data Connect VSCode extension, this is expected and not an issue. -[info] -┌─────────────────────────────────────────────────────────────┐ -│ ✔ All emulators ready! It is now safe to connect your app. │ -│ i View Emulator UI at http://127.0.0.1:4000/ │ -└─────────────────────────────────────────────────────────────┘ - -┌────────────────┬────────────────┬────────────────────────────┐ -│ Emulator │ Host:Port │ View in Emulator UI │ -├────────────────┼────────────────┼────────────────────────────┤ -│ Authentication │ 127.0.0.1:9099 │ http://127.0.0.1:4000/auth │ -└────────────────┴────────────────┴────────────────────────────┘ - Emulator Hub host: 127.0.0.1 port: 4400 - Other reserved ports: 4500 - -Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files. - -[info] i To verify the phone number +2348145495544, use the code 544557. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 544557."}} -[info] i To verify the phone number +2348145495544, use the code 227440. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 227440."}} -[info] i To verify the phone number +2348145495544, use the code 777655. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 777655."}} -[info] i To verify the phone number +2348145495544, use the code 309002. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 309002."}} -[info] i To verify the phone number +2348145495544, use the code 227291. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 227291."}} -[info] i To verify the phone number +2348145495544, use the code 419134. {"metadata":{"emulator":{"name":"auth"},"message":"To verify the phone number +2348145495544, use the code 419134."}} -[warn] ⚠ Received a signed JWT. Auth Emulator does not validate JWTs and IS NOT SECURE {"metadata":{"emulator":{"name":"auth"},"message":"Received a signed JWT. Auth Emulator does not validate JWTs and IS NOT SECURE"}} -[warn] ⚠ Received a signed JWT. Auth Emulator does not validate JWTs and IS NOT SECURE {"metadata":{"emulator":{"name":"auth"},"message":"Received a signed JWT. Auth Emulator does not validate JWTs and IS NOT SECURE"}} From 4b3ab5b304a30f4d5f75d20ede8d0078869dab7c Mon Sep 17 00:00:00 2001 From: Ademola Fadumo <48495111+demolaf@users.noreply.github.com> Date: Wed, 5 Nov 2025 15:07:48 +0100 Subject: [PATCH 6/7] Update samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/project.pbxproj Co-authored-by: Russell Wheatley --- .../FirebaseSwiftUIExample.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/project.pbxproj b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/project.pbxproj index 1369624ea2..4e93b41944 100644 --- a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/project.pbxproj +++ b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/project.pbxproj @@ -462,7 +462,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"FirebaseSwiftUIExample/Preview Content\""; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = YYX2P3XVJ7; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = FirebaseSwiftUIExample/Info.plist; From 9bb28d0a8f499784990d92eba5b01829c3a6c426 Mon Sep 17 00:00:00 2001 From: Ademola Fadumo Date: Wed, 5 Nov 2025 15:23:16 +0100 Subject: [PATCH 7/7] remove language code argument and revert mfaEnabled in config --- .../FirebaseSwiftUIExample/App/ContentView.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift index 7144f7e33f..0f6f583793 100644 --- a/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift +++ b/samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/App/ContentView.swift @@ -40,12 +40,11 @@ struct ContentView: View { actionCodeSettings.linkDomain = "flutterfire-e2e-tests.firebaseapp.com" actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!) let configuration = AuthConfiguration( - languageCode: "es", shouldAutoUpgradeAnonymousUsers: true, tosUrl: URL(string: "https://example.com/tos"), privacyPolicyUrl: URL(string: "https://example.com/privacy"), emailLinkSignInActionCodeSettings: actionCodeSettings, - mfaEnabled: false + mfaEnabled: true ) authService = AuthService( @@ -69,8 +68,6 @@ struct ContentView: View { ) ) .withEmailSignIn() - - authService.auth.useEmulator(withHost: "127.0.0.1", port: 9099) } let authService: AuthService