I am utilizing Firebase and getting an error which results in perpetual loading on my loginView.
Right here is the error I get within the console when I attempt to create an account (it save the data to the database efficiently);
I0000 00:00:1732198505.199351 570520 subchannel.cc:806] subchannel 0x1603cb400 {deal with=ipv6:%5B2607:f8b0:4007:801::200apercent5D:443, args={grpc.client_channel_factory=0x300855160, grpc.default_authority=firestore.googleapis.com, grpc.http2_scheme=https, grpc.inside.channel_credentials=0x302e04d80, grpc.inside.client_channel_call_destination=0x106089e28, grpc.inside.event_engine=0x300843450, grpc.inside.security_connector=0x302439380, grpc.inside.subchannel_pool=0x3021080e0, grpc.keepalive_time_ms=30000, grpc.primary_user_agent=grpc-c++/1.65.1, grpc.resource_quota=0x3005580f0, grpc.server_uri=dns:///firestore.googleapis.com}}: join failed (UNKNOWN:(area:NSPOSIXErrorDomain, code:50, description:The operation couldn’t be accomplished. Community is down) {grpc_status:2, created_time:”2024-11-21T06:15:05.198564-08:00″, file_line:150, file:”/var/folders/hn/5bx1f4_d4ds5vhwhkxc7vdcr0000gn/T/ZipRelease/2024-07-25T04-01-28/project-ios/Pods/gRPC-Core/src/core/lib/transport/error_utils.cc”}), backing off for 995 ms
Saved Efficiently
My swiftUI loginView code;
import SwiftUI
import PhotosUI
import Firebase
import FirebaseCore
import FirebaseAuth
import FirebaseStorage
import FirebaseFirestore
import FirebaseStorageCombineSwift
import FirebaseFirestoreCombineSwift
struct LoginView: View {
// MARK: Person Particulars
@State var emailID: String = ""
@State var password: String = ""
@State var createAccount: Bool = false
@State var showError: Bool = false
@State var errorMessage: String = ""
@State var isLoading: Bool = false
// MARK Person Defaults
@AppStorage("user_profile_url") var profileURL: URL?
@AppStorage("user_name") var userNameStored: String = ""
@AppStorage("user_UID") var userUID: String = ""
@AppStorage("log_status") var logStatus: Bool = false
var physique: some View {
VStack(spacing: 10){
Textual content("Let's Signal In")
.font(.largeTitle.daring())
.hAlign(.main)
Textual content("Welcome again, nYou have been missed")
.font(.title3)
.hAlign(.main)
VStack(spacing: 12){
TextField("E-mail", textual content: $emailID)
.textContentType(.emailAddress)
.border(1, .grey.opacity(0.5))
.padding(.prime,25)
SecureField("Password", textual content: $password)
.textContentType(.emailAddress)
.border(1, .grey.opacity(0.5))
Button("Reset password", motion: loginUser)
.font(.callout)
.fontWeight(.medium)
.tint(.black)
.hAlign(.trailing)
Button(motion: loginUser) {
// MARK: Login Button
Textual content("Signal In")
.font(.title3.daring())
.foregroundColor(.white)
.hAlign(.heart)
.fillView(Colour("LimeGreen"))
}
.padding(.prime,10)
Button {
createAccount.toggle()
} label: {
// MARK: Login Button
Textual content("Create Account")
.font(.title3.daring())
.foregroundColor(Colour("SignUpTxt"))
.hAlign(.heart)
.fillView(Colour("SignUpBtn"))
}
.padding(.prime,10)
}
// MARK: Register Button
VStack {
HStack{
Textual content("Want Assist?")
.foregroundColor(Colour("LoginText"))
}
.padding(.backside,5)
Button("Reset Password", motion: resetPassword)
.font(.callout)
.fontWeight(.medium)
.tint(Colour("LimeGreen"))
.hAlign(.heart)
}
.vAlign(.backside)
}
.vAlign(.prime)
.padding(15)
.overlay(content material: {
LoadingView(present: $isLoading)
})
// MARK: Register View VIA Sheets
.fullScreenCover(isPresented: $createAccount) {
RegisterView()
}
// MARK: Displaying Error/Alert
.alert(errorMessage, isPresented: $showError, actions: {})
}
func loginUser(){
isLoading = true
Activity{
do{
strive await Auth.auth().signIn(withEmail: emailID, password: password)
print("Person Discovered")
strive await fetchUser()
}catch{
await setError(error)
}
}
}
// MARK: is person discovered then fetch knowledge from firestore
func fetchUser()async throws{
guard let userID = Auth.auth().currentUser?.uid else{return}
let person = strive await Firestore.firestore().assortment("Customers").doc(userID).getDocument(as: Person.self)
// MARK: MUST UPDAT UI ON MAIN THREAD
await MainActor.run(physique: {
// Setting UserDefaults knowledge and altering apps auth standing
userUID = userID
userNameStored = person.username
profileURL = person.userProfileURL
logStatus = true
})
}
func resetPassword(){
Activity{
do{
strive await Auth.auth().sendPasswordReset(withEmail: emailID)
print("Hyperlink Despatched")
}catch{
await setError(error)
}
}
}
// MARK: Show error by way of alert
func setError(_ error: Error)async{
// MARK UI should be up to date on most important thread
await MainActor.run(physique: {
errorMessage = error.localizedDescription
showError.toggle()
isLoading = false
})
}
}
// MARK: Register View
struct RegisterView: View{
// MARK: Person Particulars
@State var emailID: String = ""
@State var password: String = ""
@State var userName: String = ""
@State var userBio: String = ""
@State var userBioLink: String = ""
@State var userProfilePicData: Information?
// MARK: View Properties
@Setting(.dismiss) var dismiss
@State var showImagePicker: Bool = false
@State var photoItem: PhotosPickerItem?
@State var showError: Bool = false
@State var errorMessage: String = ""
@State var isLoading: Bool = false
// MARK: UserDefaults
@AppStorage("log_status") var logStatus: Bool = false
@AppStorage("user_profile_url") var profileURL: URL?
@AppStorage("user_name") var userNameStored: String = ""
@AppStorage("user_UID") var userUID: String = ""
var physique: some View{
VStack(spacing: 10){
Textual content("Create your nAccount")
.font(.largeTitle.daring())
.hAlign(.main)
Textual content("Whats up, Plant Particular person nYou'll adore it right here!")
.font(.title3)
.hAlign(.main)
// MARK: For smaller Dimension Optimization
ViewThatFits {
ScrollView(. vertical, showsIndicators: false) {
HelperView()
}
HelperView()
}
// MARK: Register Button
VStack {
HStack{
Textual content("Have already got an account?")
.foregroundColor(Colour("LoginText"))
}
.padding(.backside,5)
Button("Login"){
dismiss()
}
.font(.callout)
.fontWeight(.medium)
.tint(Colour("LimeGreen"))
.hAlign(.heart)
}
.vAlign(.backside)
}
.vAlign(.prime)
.padding(15)
.overlay(content material: {
LoadingView(present: $isLoading)
})
.photosPicker(isPresented: $showImagePicker, choice: $photoItem)
.onChange(of: photoItem) {
oldValue, newValue in
// MARK: Extracting UIImage PhotoITem
if let newValue{
Activity{
do{
guard let imageData = strive await newValue.loadTransferable(kind: Information.self) else {
return }
// MARK: UI Should be up to date on most important thread
await MainActor.run{
userProfilePicData = imageData
}
}catch{
}
}
}
}
// MARK Displaying Alert
.alert(errorMessage, isPresented: $showError, actions:{})
}
@ViewBuilder
func HelperView()->some View{
VStack(spacing: 12){
ZStack{
if let userProfilePicData,let picture = UIImage(knowledge: userProfilePicData){
Picture(uiImage: picture)
.resizable()
.aspectRatio(contentMode: .fill)
} else{
Picture("NullProfileImg")
.resizable()
.aspectRatio(contentMode: .fill)
}
}
.body(width: 85, top: 85)
.clipShape(Circle())
.contentShape(Circle())
.onTapGesture {
showImagePicker.toggle()
}
.padding(.prime,25)
TextField("Username", textual content: $userName)
.textContentType(.emailAddress)
.border(1, .grey.opacity(0.5))
TextField("E-mail", textual content: $emailID)
.textContentType(.emailAddress)
.border(1, .grey.opacity(0.5))
SecureField("Password", textual content: $password)
.textContentType(.emailAddress)
.border(1, .grey.opacity(0.5))
TextField("About Me", textual content: $userBio,axis: .vertical)
.body(minHeight: 100,alignment: .prime)
.textContentType(.emailAddress)
.border(1, .grey.opacity(0.5))
TextField("Hyperlink", textual content: $userBioLink)
.textContentType(.emailAddress)
.border(1, .grey.opacity(0.5))
Button(motion: registerUser){
// MARK: Login Button
Textual content("Create Account")
.font(.title3.daring())
.foregroundColor(.white)
.hAlign(.heart)
.fillView(Colour("LimeGreen"))
}
.disableWithOpacity(userName == "" || userBio == "" || emailID == "" || password == "" || userProfilePicData == nil)
.padding(.prime,10)
}
}
func registerUser(){
isLoading = true
Activity{
do{
// Step 1: Create Firebase Account
strive await Auth.auth().createUser(withEmail: emailID, password: password)
// Step 2: Add profile pic to firebase storage
guard let userUID = Auth.auth().currentUser?.uid else {return}
guard let imageData = userProfilePicData else {return}
let storageRef = Storage.storage().reference().little one("profile_Images").little one(userUID)
let _ = strive await storageRef.putDataAsync(imageData)
// Step 3: Downlaoding photograph url
let downloadURL = strive await storageRef.downloadURL()
// Step 4: Creating person Firestore object
let person = Person(username: userName, userBio: userBio, userBioLink: userBioLink, userUID: userUID, userEmail: emailID, userProfileURL: downloadURL)
// Step 5: Saving person doc into firestore database
let _ = strive Firestore.firestore().assortment("Customers").doc(userUID).setData(from: person, completion: {
error in
if error == nil{
// MARK: print efficiently saved
print("Saved Efficiently")
userNameStored = userName
self.userUID = userUID
profileURL = downloadURL
logStatus = true
}
})
}catch{
// MARK: Deleting created account in case of failure
strive await Auth.auth().currentUser?.delete()
await setError(error)
}
}
}
func resetPassword(){
Activity{
do{
strive await Auth.auth().sendPasswordReset(withEmail: emailID)
print("person discovered")
}catch{
await setError(error)
}
}
}
// MARK: Displaying Error VIA Alert
func setError(_ error: Error)async{
// MARK: UI should be replace don most important thread
await MainActor.run(physique: {
errorMessage = error.localizedDescription
showError.toggle()
isLoading = false
})
}
}
#Preview {
RegisterView()
}
// MARK: View Extension For UI Constructing
extension View{
// MARK: Disabling with opacity
func disableWithOpacity(_ situation: Bool)->some View{
self
.disabled(situation)
.opacity(situation ? 0.6 : 1)
}
func hAlign(_ alignment: Alignment)->some View{
self
.body(maxWidth: .infinity,alignment: alignment)
}
func vAlign(_ alignment: Alignment)->some View{
self
.body(maxHeight: .infinity,alignment: alignment)
}
// MARK: Customized border view with padding
func border(_ width: CGFloat,_ coloration: Colour)->some View{
self
.padding(.horizontal,15)
.padding(.vertical,10)
.background {
RoundedRectangle(cornerRadius: 20, type: .steady)
.stroke(coloration, lineWidth: width)
}
}
// MARK: Customized fill view with padding
func fillView(_ coloration: Colour)->some View{
self
.padding(.horizontal,15)
.padding(.vertical,10)
.background {
RoundedRectangle(cornerRadius: 25, type: .steady)
.fill(coloration)
}
}
}
As soon as a person faucets the create account button the app ought to connect with Firebase storage to avoid wasting the person information and picture after which load to the mainView()