1

i would like to add the possibility to send a verification email during registration. How could i insert "sendEmailVerificationWithCompletion" inside the function and within the SignupView? Thanks a lot :)

import SwiftUI
import FirebaseAuth

// Add code here:
static func createUser(withEmail email:String, name: String, password:String, completionHandler:@escaping (Result<Bool,Error>) -> Void) {
    Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
        if let err = error {
            completionHandler(.failure(err))
            return
        }
        guard let _ = authResult?.user else {
            completionHandler(.failure(error!))
            return
        }
        let data = FBUser.dataDict(uid: authResult!.user.uid, name: name, email: authResult!.user.email!)
        
        FBFirestore.mergeFBUser(data, uid: authResult!.user.uid) { (result) in
            completionHandler(result)
        }
        completionHandler(.success(true))
    }
}

//And add code here:
struct SignUpView: View {
    var body: some View {
        VStack(spacing: 20 ) {
            Button(action: {
                FBAuth.createUser(withEmail: self.user.email, name: self.user.fullname, password: self.user.password) { (result) in
                    switch result {
                    case .failure(let error):
                        self.errorString = error.localizedDescription
                        self.showError = true
                    case .success(_):
                        print("Account creation successful")
                    }
                }
            }) {
                Text("Register")
            }
        }
    }
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

1 Answers1

3

You can tell Firebase to send a verification email to the current user at any time after that user is signed in. For example, you could do so right after the user's account is created:

Auth.auth().createUser(withEmail: email, password: password) { (authResult, error) in
    if let err = error {
        completionHandler(.failure(err))
        return
    }
    guard let _ = authResult?.user else {
        completionHandler(.failure(error!))
        return
    }

    // send verification email
    Auth.auth().currentUser?.sendEmailVerification { (error) in
      // ...
    }

    // write profile to database
    let data = FBUser.dataDict(uid: authResult!.user.uid, name: name, email: authResult!.user.email!)
    
    FBFirestore.mergeFBUser(data, uid: authResult!.user.uid) { (result) in
        completionHandler(result)
    }
    completionHandler(.success(true))
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thanks a lot :) I did it. The email with the link arrives correctly, only that it logs in even if it does not confirm the email. How can I add a rule that says it should not log in if the link has not been confirmed before? –  Aug 03 '20 at 17:40
  • That is not possible, but also not needed. What you probably want is for the app to not continue when the account isn't verified, which you can do by checking the user's [`isEmailVerified`](https://firebase.google.com/docs/reference/swift/firebaseauth/api/reference/Classes/User#isemailverified). Then to make data access secure, you'll want to check that same property in the server before allowing them to access any data. This topic has been covered before, so have a look at https://stackoverflow.com/a/56670780, https://stackoverflow.com/a/48029049 and https://stackoverflow.com/a/55328819 – Frank van Puffelen Aug 03 '20 at 17:47
  • Ok, I'll try it :) Thanks again –  Aug 03 '20 at 19:55