最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - Firestore API failed to connect crashing my app - Stack Overflow

programmeradmin0浏览0评论

Every time I switch from mock Data to real data from my Firebase, my app crashes:

As soon as I change this 3 lines of code my app crashes

Main Code

import SwiftUI

struct InboxView: View {
    
    @State private var showNewMessageView = false
//    @StateObject var viewModel = InboxViewModel() // uncomment this
    @State private var user = User.MOCK_USER // comment out this
    
//    private var user: User? { //uncomment this
//        return viewModel.currentUser
//    }
    
    var body: some View {
        NavigationStack {
            ScrollView {
                ActiveNowView()
                
                List {
                    ForEach(0 ... 10, id: \.self) { message in
                        InboxRowView()
                    }
                }
                .listStyle(PlainListStyle())
                .frame(height: UIScreen.main.bounds.height - 120)
            }
            .navigationDestination(for: User.self, destination: { user in
                ProfileView(user: user)
            })
            .fullScreenCover(isPresented: $showNewMessageView, content: {
                NewMessageView()
            })
            .toolbar {
                ToolbarItem(placement: .topBarLeading) {
                    HStack {
                        NavigationLink(value: user) {
                            CircularProfileImageView(user: user, size: .xsmall)
                        }
                        
                        Text("Chats")
                            .font(.title)
                            .fontWeight(.semibold)
                    }
                }
                
                ToolbarItem(placement: .topBarTrailing) {
                    Button {
                        showNewMessageView.toggle()
                    } label: {
                        Image(systemName: "square.and.pencil.circle.fill")
                            .resizable()
                            .frame(width: 32, height: 32)
                            .foregroundStyle(.black, Color(.systemGray5))
                    }
                }
            }
        }
    }
}

InboxViewModel

import Foundation
import Combine
import Firebase

class InboxViewModel: ObservableObject {
    
    @Published var currentUser: User?
    
    private var cancellabels = Set<AnyCancellable>()
    
    init() {
        setupSuscribers()
    }
    
    private func setupSuscribers() {
        UserService.shared.$currentUser.sink { [weak self] user in
            self?.currentUser = user
        }.store(in: &cancellabels)
    }
}

User

import FirebaseFirestore
import SwiftUI
import Firebase

struct User: Codable, Identifiable, Hashable {
    @DocumentID var uid: String?

    let fullname: String
    let email: String
    let profileImageUrl: String?
    
    var id: String {
        return uid ?? NSUUID().uuidString
    }
}

extension User {
    static let MOCK_USER = User(fullname: "Bruce Wayne", email: "[email protected]", profileImageUrl: "batman")
}

Authorisation Service

import Foundation
import Firebase
import FirebaseAuth
import FirebaseFirestore

class AuthService {
    
    @Published var userSession: FirebaseAuth.User?
    
    static let shared = AuthService()
    
    init() {
        self.userSession = Auth.auth().currentUser
        loadCurrentUserData()
        print("User session id is \(userSession?.uid)")
    }
    
    @MainActor
    // Log in
    func login(withEmail email: String, password: String) async throws {
        do {
            let result = try await Auth.auth().signIn(withEmail: email, password: password)
            self.userSession = result.user
            loadCurrentUserData()
        } catch {
            print("DEBUG: Failed to sign in user with error: \(error.localizedDescription)")
        }
    }
    
    @MainActor
    // Sign in
    func createUser(withEmail email: String, password: String, fullname: String) async throws {
        do {
            let result = try await Auth.auth().createUser(withEmail: email, password: password)
            self.userSession = result.user
            try await self.uploadUserData(email: email, fullname: fullname, id: result.user.uid)
            loadCurrentUserData()
        } catch {
            print("DEBUG: Failed to create user with error: \(error.localizedDescription)")
        }
    }
    
    // Log out
    func signOut() {
        do {
            try Auth.auth().signOut() // signs out on backend
            self.userSession = nil // update routing logic
            UserService.shared.currentUser = nil
        }   catch {
            print("DEBUG: Failed to sign out with error: \(error.localizedDescription)")
        }
    }
    
    
    // Data upload
    private func uploadUserData(email: String, fullname: String, id: String) async throws {
        let user = User(fullname: fullname, email: email, profileImageUrl: nil)
        guard let encodeUser = try? Firestore.Encoder().encode(user) else { return }
        try await Firestore.firestore().collection("users").document(id).setData(encodeUser)
    }
    
    
    // bug fix (user details)
    private func loadCurrentUserData() {
        Task { try await UserService.shared.fetchCurrentUser() }
    }
}

The Terminal throws this error as soon as I run my code

I0000 00:00:1732088994.725995 1362774 subchannel:806] subchannel 0x101c70a80 {address=ipv6:%5B2404:6800:4002:81a::200a%5D:443, args={grpc.client_channel_factory=0x60000002b3e0, grpc.default_authority=firestore.googleapis, grpc.http2_scheme=https, grpc.internal.channel_credentials=0x60000263cb40, grpc.internal.client_channel_call_destination=0x103d64828, grpc.internal.event_engine=0x60000002b4e0, grpc.internal.security_connector=0x600002c2d900, grpc.internal.subchannel_pool=0x600002949500, grpc.keepalive_time_ms=30000, grpc.primary_user_agent=grpc-c++/1.65.1, grpc.resource_quota=0x600000c99680, grpc.server_uri=dns:///firestore.googleapis}}: connect failed (UNKNOWN:(domain:NSPOSIXErrorDomain, code:50, description:The operation couldn’t be completed. Network is down) {file:"/var/folders/hn/5bx1f4_d4ds5vhwhkxc7vdcr0000gn/T/ZipRelease/2024-07-25T04-01-28/project-ios/Pods/gRPC-Core/src/core/lib/transport/error_utils", file_line:150, created_time:"2024-11-20T13:19:54.724606+05:30", grpc_status:2}), backing off for 874 ms

DEBUG: Current user is Optional(Messenger.User(_uid: FirebaseFirestore.DocumentID<Swift.String>(value: Optional("Tg2TbvUlWBdjtL1XKkFJD6MeGKn1")), fullname: "Bruce Wayne", email: "[email protected]", profileImageUrl: nil))

Every time I switch from mock Data to real data from my Firebase, my app crashes:

As soon as I change this 3 lines of code my app crashes

Main Code

import SwiftUI

struct InboxView: View {
    
    @State private var showNewMessageView = false
//    @StateObject var viewModel = InboxViewModel() // uncomment this
    @State private var user = User.MOCK_USER // comment out this
    
//    private var user: User? { //uncomment this
//        return viewModel.currentUser
//    }
    
    var body: some View {
        NavigationStack {
            ScrollView {
                ActiveNowView()
                
                List {
                    ForEach(0 ... 10, id: \.self) { message in
                        InboxRowView()
                    }
                }
                .listStyle(PlainListStyle())
                .frame(height: UIScreen.main.bounds.height - 120)
            }
            .navigationDestination(for: User.self, destination: { user in
                ProfileView(user: user)
            })
            .fullScreenCover(isPresented: $showNewMessageView, content: {
                NewMessageView()
            })
            .toolbar {
                ToolbarItem(placement: .topBarLeading) {
                    HStack {
                        NavigationLink(value: user) {
                            CircularProfileImageView(user: user, size: .xsmall)
                        }
                        
                        Text("Chats")
                            .font(.title)
                            .fontWeight(.semibold)
                    }
                }
                
                ToolbarItem(placement: .topBarTrailing) {
                    Button {
                        showNewMessageView.toggle()
                    } label: {
                        Image(systemName: "square.and.pencil.circle.fill")
                            .resizable()
                            .frame(width: 32, height: 32)
                            .foregroundStyle(.black, Color(.systemGray5))
                    }
                }
            }
        }
    }
}

InboxViewModel

import Foundation
import Combine
import Firebase

class InboxViewModel: ObservableObject {
    
    @Published var currentUser: User?
    
    private var cancellabels = Set<AnyCancellable>()
    
    init() {
        setupSuscribers()
    }
    
    private func setupSuscribers() {
        UserService.shared.$currentUser.sink { [weak self] user in
            self?.currentUser = user
        }.store(in: &cancellabels)
    }
}

User

import FirebaseFirestore
import SwiftUI
import Firebase

struct User: Codable, Identifiable, Hashable {
    @DocumentID var uid: String?

    let fullname: String
    let email: String
    let profileImageUrl: String?
    
    var id: String {
        return uid ?? NSUUID().uuidString
    }
}

extension User {
    static let MOCK_USER = User(fullname: "Bruce Wayne", email: "[email protected]", profileImageUrl: "batman")
}

Authorisation Service

import Foundation
import Firebase
import FirebaseAuth
import FirebaseFirestore

class AuthService {
    
    @Published var userSession: FirebaseAuth.User?
    
    static let shared = AuthService()
    
    init() {
        self.userSession = Auth.auth().currentUser
        loadCurrentUserData()
        print("User session id is \(userSession?.uid)")
    }
    
    @MainActor
    // Log in
    func login(withEmail email: String, password: String) async throws {
        do {
            let result = try await Auth.auth().signIn(withEmail: email, password: password)
            self.userSession = result.user
            loadCurrentUserData()
        } catch {
            print("DEBUG: Failed to sign in user with error: \(error.localizedDescription)")
        }
    }
    
    @MainActor
    // Sign in
    func createUser(withEmail email: String, password: String, fullname: String) async throws {
        do {
            let result = try await Auth.auth().createUser(withEmail: email, password: password)
            self.userSession = result.user
            try await self.uploadUserData(email: email, fullname: fullname, id: result.user.uid)
            loadCurrentUserData()
        } catch {
            print("DEBUG: Failed to create user with error: \(error.localizedDescription)")
        }
    }
    
    // Log out
    func signOut() {
        do {
            try Auth.auth().signOut() // signs out on backend
            self.userSession = nil // update routing logic
            UserService.shared.currentUser = nil
        }   catch {
            print("DEBUG: Failed to sign out with error: \(error.localizedDescription)")
        }
    }
    
    
    // Data upload
    private func uploadUserData(email: String, fullname: String, id: String) async throws {
        let user = User(fullname: fullname, email: email, profileImageUrl: nil)
        guard let encodeUser = try? Firestore.Encoder().encode(user) else { return }
        try await Firestore.firestore().collection("users").document(id).setData(encodeUser)
    }
    
    
    // bug fix (user details)
    private func loadCurrentUserData() {
        Task { try await UserService.shared.fetchCurrentUser() }
    }
}

The Terminal throws this error as soon as I run my code

I0000 00:00:1732088994.725995 1362774 subchannel:806] subchannel 0x101c70a80 {address=ipv6:%5B2404:6800:4002:81a::200a%5D:443, args={grpc.client_channel_factory=0x60000002b3e0, grpc.default_authority=firestore.googleapis, grpc.http2_scheme=https, grpc.internal.channel_credentials=0x60000263cb40, grpc.internal.client_channel_call_destination=0x103d64828, grpc.internal.event_engine=0x60000002b4e0, grpc.internal.security_connector=0x600002c2d900, grpc.internal.subchannel_pool=0x600002949500, grpc.keepalive_time_ms=30000, grpc.primary_user_agent=grpc-c++/1.65.1, grpc.resource_quota=0x600000c99680, grpc.server_uri=dns:///firestore.googleapis}}: connect failed (UNKNOWN:(domain:NSPOSIXErrorDomain, code:50, description:The operation couldn’t be completed. Network is down) {file:"/var/folders/hn/5bx1f4_d4ds5vhwhkxc7vdcr0000gn/T/ZipRelease/2024-07-25T04-01-28/project-ios/Pods/gRPC-Core/src/core/lib/transport/error_utils", file_line:150, created_time:"2024-11-20T13:19:54.724606+05:30", grpc_status:2}), backing off for 874 ms

DEBUG: Current user is Optional(Messenger.User(_uid: FirebaseFirestore.DocumentID<Swift.String>(value: Optional("Tg2TbvUlWBdjtL1XKkFJD6MeGKn1")), fullname: "Bruce Wayne", email: "[email protected]", profileImageUrl: nil))

Share Improve this question edited Nov 22, 2024 at 13:22 Anubhav Tomar asked Nov 20, 2024 at 7:52 Anubhav TomarAnubhav Tomar 13 bronze badges 2
  • 1 "Network is down", have you enabled network access for your app? (Signing & Capabilities -> App Sandbox -> Incoming/Outgoing connections) – Joakim Danielson Commented Nov 20, 2024 at 8:08
  • It's already enabled. – Anubhav Tomar Commented Nov 20, 2024 at 9:04
Add a comment  | 

1 Answer 1

Reset to default 0

The app crashes when switching from mock data to real Firebase data. The terminal log includes a Network is down error and shows that the profileImageUrl is nil, leading to a crash when rendering the profile image.

Update the User Code :

var safeProfileImageUrl: String {
    return profileImageUrl ?? "defaultImageURL"
}

When switching from mock data to real data, the InboxViewModel is responsible for fetching and observing the real user data. If the currentUser is nil, your app may crash when trying to access properties like profileImageUrl.

发布评论

评论列表(0)

  1. 暂无评论