Skip to content

Commit

Permalink
Merge pull request #62 from techstartucalgary/firebase-authentication
Browse files Browse the repository at this point in the history
Firebase authentication
  • Loading branch information
ParsaKargari authored Feb 8, 2024
2 parents 9f4e962 + 4cd68ba commit 65c6e58
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 54 deletions.
Binary file added .DS_Store
Binary file not shown.
Binary file modified Rethread/.DS_Store
Binary file not shown.
28 changes: 17 additions & 11 deletions Rethread/Rethread.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
983286CF2B05698F00851B19 /* RethreadUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RethreadUITests.swift; sourceTree = "<group>"; };
983286D12B05698F00851B19 /* RethreadUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RethreadUITestsLaunchTests.swift; sourceTree = "<group>"; };
983D40F82B68B81800905D4E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
983D40FA2B68D13E00905D4E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
98434A5C2B63342700F81127 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
9868A7DD2B1FAE780063D9BA /* ButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonStyles.swift; sourceTree = "<group>"; };
988A0F982B3C112300ACDC90 /* DatePickerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickerModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -143,20 +144,20 @@
path = Models;
sourceTree = "<group>";
};
7C9AA2D12B0EC3BC00EF6F36 /* Extensions */ = {
7C9AA2D42B0ECADF00EF6F36 /* Styles */ = {
isa = PBXGroup;
children = (
9868A7DD2B1FAE780063D9BA /* ButtonStyles.swift */,
98A1838B2B38D32A001E324A /* ColorPalette.swift */,
);
path = Extensions;
path = Styles;
sourceTree = "<group>";
};
7C9AA2D42B0ECADF00EF6F36 /* Styles */ = {
980DACBB2B71E7110008B88A /* Extensions */ = {
isa = PBXGroup;
children = (
9868A7DD2B1FAE780063D9BA /* ButtonStyles.swift */,
98A1838B2B38D32A001E324A /* ColorPalette.swift */,
);
path = Styles;
path = Extensions;
sourceTree = "<group>";
};
983286A82B05698E00851B19 = {
Expand Down Expand Up @@ -184,8 +185,9 @@
983286B32B05698E00851B19 /* Rethread */ = {
isa = PBXGroup;
children = (
7C9AA2D12B0EC3BC00EF6F36 /* Extensions */,
983D40FA2B68D13E00905D4E /* Info.plist */,
7C9AA2D42B0ECADF00EF6F36 /* Styles */,
980DACBB2B71E7110008B88A /* Extensions */,
9897C7712B3E6BF600EDE9D9 /* Components */,
98F525CC2B46A8E900CCAD78 /* VideoPlayer */,
7C9AA2CC2B0EC02600EF6F36 /* Models */,
Expand Down Expand Up @@ -621,9 +623,11 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"Rethread/Preview Content\"";
DEVELOPMENT_TEAM = B83J2A83H6;
DEVELOPMENT_TEAM = 4GW9NWA7H9;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Rethread/Info.plist;
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Rethread needs your location";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
Expand All @@ -635,7 +639,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = techstart.Rethread;
PRODUCT_BUNDLE_IDENTIFIER = techstart.Rethread2;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
Expand All @@ -653,9 +657,11 @@
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"Rethread/Preview Content\"";
DEVELOPMENT_TEAM = B83J2A83H6;
DEVELOPMENT_TEAM = 4GW9NWA7H9;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Rethread/Info.plist;
INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Rethread needs your location";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
Expand All @@ -667,7 +673,7 @@
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = techstart.Rethread;
PRODUCT_BUNDLE_IDENTIFIER = techstart.Rethread2;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
Expand Down
17 changes: 17 additions & 0 deletions Rethread/Rethread/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>com.googleusercontent.apps.69711373157-smt51cs82nik0nceo6slguta9vmaip00</string>
</array>
</dict>
</array>
</dict>
</plist>
35 changes: 31 additions & 4 deletions Rethread/Rethread/UserAuthentication/AuthViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import FirebaseFirestoreSwift
class AuthViewModel: ObservableObject {
@Published var userSession: FirebaseAuth.User?
@Published var currentUser: User?
@Published var CLIENT_CODE: String = ""
private var verificationId: String?

init(){
self.userSession = Auth.auth().currentUser
Expand All @@ -33,19 +35,19 @@ class AuthViewModel: ObservableObject {
do {
let result = try await Auth.auth().createUser(withEmail: formData.email, password: formData.password)
self.userSession = result.user

let user = User(id: result.user.uid, firstname: formData.firstName, lastname: formData.lastName,
email: formData.email, dateOfBirth: formData.dateOfBirth, gender: formData.gender,
email: formData.email, dateOfBirth: formData.dateOfBirth, gender: formData.gender,
phoneNumber: formData.phoneNumber,postalCode: formData.postalCode, onboardingComplete: false)

let encodedUser = try Firestore.Encoder().encode(user)
try await Firestore.firestore().collection("users").document(user.id).setData(encodedUser)
await fetchUser()
} catch {
print("DEBUG: Error creating user: \(error.localizedDescription)")
}
}

func updateOnboardingComplete() async throws {
do {
let userRef = Firestore.firestore().collection("users").document(userSession!.uid)
Expand Down Expand Up @@ -78,4 +80,29 @@ class AuthViewModel: ObservableObject {
guard let snapshot = try? await Firestore.firestore().collection("users").document(uid).getDocument() else {return}
self.currentUser = try? snapshot.data(as: User.self)
}



// func sendPhoneAuth() async {
// PhoneAuthProvider.provider().verifyPhoneNumber("+16505551111", uiDelegate: nil) { [weak self] verificationID, error in
// guard let verificationID = verificationID, error == nil else {
// print("DEBUG: Error sending phone auth: \(error!.localizedDescription)")
// return
// }
// self?.verificationId = verificationID
// }
// }
// func verifyPhoneAuth(otp: String) async {
// guard let verificationId = self.verificationId else {return}
// let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationId, verificationCode: otp)
//
// Auth.auth().signIn(with: credential) { (result, error) in
// if let error = error {
// print("DEBUG: Error verifying phone auth: \(error.localizedDescription)")
// return
// }
// self.userSession = result?.user
// }
// }

}
3 changes: 3 additions & 0 deletions Rethread/Rethread/Views/MainView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,12 @@ struct MainView: View {
struct CustomTextField: View {
var placeholder: String
@Binding var text: String
var disableAutocorrection: Bool = false

var body: some View {
TextField(placeholder, text: $text)
.disableAutocorrection(disableAutocorrection)
.autocapitalization(disableAutocorrection ? .none : .sentences)
.foregroundColor(Color.primaryTextColor)
.padding()
.overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray, lineWidth: 1))
Expand Down
1 change: 1 addition & 0 deletions Rethread/Rethread/Views/OnboardingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ struct OnboardingStep {
let maxSelections: Int
}

// MARK: Onboarding Questions
let onboardingSteps = [
OnboardingStep(question: "What is your favorite color?",
options: ["Red", "Green", "Blue", "Purple"],
Expand Down
21 changes: 14 additions & 7 deletions Rethread/Rethread/Views/SignUpView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ struct SignUpView: View {
.padding(.leading, 25)
.padding(.top, 20)

CustomTextField(placeholder: "First Name", text: $formData.firstName)
CustomTextField(placeholder: "First Name", text: $formData.firstName, disableAutocorrection: true)
.padding(.leading, 25)
.padding(.top, 9)
}
Expand All @@ -96,7 +96,7 @@ struct SignUpView: View {
.padding(.trailing, 25)
.padding(.top, 20)

CustomTextField(placeholder: "Last Name", text: $formData.lastName)
CustomTextField(placeholder: "Last Name", text: $formData.lastName, disableAutocorrection: true)
.padding(.trailing, 25)
.padding(.top, 9)
}
Expand All @@ -107,7 +107,7 @@ struct SignUpView: View {
.padding(.horizontal, 25)
.padding(.top, 20)

CustomTextField(placeholder: "Email", text: $formData.email)
CustomTextField(placeholder: "Email", text: $formData.email, disableAutocorrection: true)
.padding(.horizontal, 25)
.padding(.top, 9)
HStack {
Expand Down Expand Up @@ -162,7 +162,7 @@ struct SignUpView: View {
.padding(.horizontal, 25)
.padding(.top, 20)

CustomTextField(placeholder: "Phone Number", text: $formData.phoneNumber)
CustomTextField(placeholder: "Phone Number", text: $formData.phoneNumber, disableAutocorrection: true)
.padding(.horizontal, 25)
.padding(.top, 9)

Expand Down Expand Up @@ -197,7 +197,7 @@ struct SignUpView: View {
.padding(.horizontal, 25)
.padding(.top, 20)

CustomTextField(placeholder: "Postal Code", text: $formData.postalCode)
CustomTextField(placeholder: "Postal Code", text: $formData.postalCode, disableAutocorrection: true)
.padding(.horizontal, 25)
.padding(.top, 9)

Expand All @@ -212,9 +212,16 @@ struct SignUpView: View {
Button("Join Us") {
// Handle sign up
print(formData)
// Check form validity

self.isShowingVerification = true
// Send verification code
Task {
do {
self.isShowingVerification = true
} catch {
print("DEBUG: Error starting auth: \(error.localizedDescription)")
}
}

}
.buttonStyle(PrimaryButtonStyle(width: 300, isDisabled: !areTermsAccepted))
.disabled(!areTermsAccepted)
Expand Down
63 changes: 31 additions & 32 deletions Rethread/Rethread/Views/VerificationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ struct VerificationView: View {
var formData: SignUpFormData?
@Environment(\.dismiss) private var dismiss
@EnvironmentObject var viewModel: AuthViewModel
@State private var isLoading = false

// OTP Info
@State var otpFields: [String] = Array(repeating: "", count: 6)
Expand Down Expand Up @@ -53,43 +54,41 @@ struct VerificationView: View {

// Bottom content, including the sign-in button
VStack (spacing: 16) {
Button("Verify") {
// Handle sign in
if isSignIn {
// Sign in
print("Sign in")
} else {
// Confirm OTP. If successful, create user.
let otpCode = otpFields.joined()
Task {
do {
if let formData = formData {
try await viewModel.createUser(formData: formData)
if isLoading {
ProgressView()
} else {
Button("Verify") {
// Handle sign in
isLoading = true
if isSignIn {
// MARK: SIGN IN OTP

} else {
// MARK: SIGN UP OTP
let otpCode = otpFields.joined()
Task {
do {
try await viewModel.createUser(formData: formData!)
dismiss()
} catch {
print("DEBUG: Error verifying user: \(error.localizedDescription)")
}
} catch {
print("DEBUG: Error verifying code: \(error.localizedDescription)")
}
}


dismiss()
}
}
.buttonStyle(PrimaryButtonStyle(width: 300, isDisabled: checkStates()))
.disabled(checkStates())


Button(action: {
if let phoneNumber = formData?.phoneNumber {
Task {

}
.buttonStyle(PrimaryButtonStyle(width: 300, isDisabled: checkStates() || isLoading))
.disabled(checkStates() || isLoading)


Button(action: {
// MARK: REQUEST NEW CODE

}) {
Text("Request new code")
.foregroundColor(Color.primaryColor)
.fontWeight(.semibold)
.underline() // Underlined text
}
}) {
Text("Request new code")
.foregroundColor(Color.primaryColor)
.fontWeight(.semibold)
.underline() // Underlined text
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom) // Aligns buttons to the bottom
Expand Down

0 comments on commit 65c6e58

Please sign in to comment.