Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "whereareyou-16ea6"
}
}
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@ build/
.env.local
**/.env
**/.env.local
!**/.env.example
!**/.env.example

# Firebase
GoogleService-Info.plist
*-debug.log
ui-debug.log
57 changes: 57 additions & 0 deletions WhereAreYou/WhereAreYou.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
objects = {

/* Begin PBXBuildFile section */
8C332F1D303DDB39008375EC /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 8C332F1C303DDB39008375EC /* FirebaseAnalytics */; };
8C332F20303DEAB1008375EC /* FirebaseFirestore in Frameworks */ = {isa = PBXBuildFile; productRef = 8C332F1F303DEAB1008375EC /* FirebaseFirestore */; };
8C332F22303DEABA008375EC /* FirebaseDatabase in Frameworks */ = {isa = PBXBuildFile; productRef = 8C332F21303DEABA008375EC /* FirebaseDatabase */; };
8C332F24303DEAC3008375EC /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 8C332F23303DEAC3008375EC /* FirebaseAuth */; };
8C332F26303DED5E008375EC /* FirebaseStorage in Frameworks */ = {isa = PBXBuildFile; productRef = 8C332F25303DED5E008375EC /* FirebaseStorage */; };
BCAC3F343017B45700EC9102 /* NMapsMap in Frameworks */ = {isa = PBXBuildFile; productRef = BCAC3F333017B45700EC9102 /* NMapsMap */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -40,17 +45,30 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8C332F1D303DDB39008375EC /* FirebaseAnalytics in Frameworks */,
8C332F24303DEAC3008375EC /* FirebaseAuth in Frameworks */,
BCAC3F343017B45700EC9102 /* NMapsMap in Frameworks */,
8C332F22303DEABA008375EC /* FirebaseDatabase in Frameworks */,
8C332F20303DEAB1008375EC /* FirebaseFirestore in Frameworks */,
8C332F26303DED5E008375EC /* FirebaseStorage in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
8C332F1E303DEAB1008375EC /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
8C44C1D32FFCF585006DA2FC = {
isa = PBXGroup;
children = (
8C44C1DE2FFCF585006DA2FC /* WhereAreYou */,
8C332F1E303DEAB1008375EC /* Frameworks */,
8C44C1DD2FFCF585006DA2FC /* Products */,
);
sourceTree = "<group>";
Expand Down Expand Up @@ -84,6 +102,11 @@
name = WhereAreYou;
packageProductDependencies = (
BCAC3F333017B45700EC9102 /* NMapsMap */,
8C332F1C303DDB39008375EC /* FirebaseAnalytics */,
8C332F1F303DEAB1008375EC /* FirebaseFirestore */,
8C332F21303DEABA008375EC /* FirebaseDatabase */,
8C332F23303DEAC3008375EC /* FirebaseAuth */,
8C332F25303DED5E008375EC /* FirebaseStorage */,
);
productName = WhereAreYou;
productReference = 8C44C1DC2FFCF585006DA2FC /* WhereAreYou.app */;
Expand Down Expand Up @@ -115,6 +138,7 @@
minimizedProjectReferenceProxies = 1;
packageReferences = (
BCAC3F323017B45700EC9102 /* XCRemoteSwiftPackageReference "SPM-NMapsMap" */,
8C332F1B303DDB39008375EC /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = 8C44C1DD2FFCF585006DA2FC /* Products */;
Expand Down Expand Up @@ -376,6 +400,14 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
8C332F1B303DDB39008375EC /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 12.18.0;
};
};
BCAC3F323017B45700EC9102 /* XCRemoteSwiftPackageReference "SPM-NMapsMap" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/navermaps/SPM-NMapsMap";
Expand All @@ -387,6 +419,31 @@
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
8C332F1C303DDB39008375EC /* FirebaseAnalytics */ = {
isa = XCSwiftPackageProductDependency;
package = 8C332F1B303DDB39008375EC /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseAnalytics;
};
8C332F1F303DEAB1008375EC /* FirebaseFirestore */ = {
isa = XCSwiftPackageProductDependency;
package = 8C332F1B303DDB39008375EC /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseFirestore;
};
8C332F21303DEABA008375EC /* FirebaseDatabase */ = {
isa = XCSwiftPackageProductDependency;
package = 8C332F1B303DDB39008375EC /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseDatabase;
};
8C332F23303DEAC3008375EC /* FirebaseAuth */ = {
isa = XCSwiftPackageProductDependency;
package = 8C332F1B303DDB39008375EC /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseAuth;
};
8C332F25303DED5E008375EC /* FirebaseStorage */ = {
isa = XCSwiftPackageProductDependency;
package = 8C332F1B303DDB39008375EC /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseStorage;
};
BCAC3F333017B45700EC9102 /* NMapsMap */ = {
isa = XCSwiftPackageProductDependency;
package = BCAC3F323017B45700EC9102 /* XCRemoteSwiftPackageReference "SPM-NMapsMap" */;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions WhereAreYou/WhereAreYou/Core/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

import UIKit
import NMapsMap
import FirebaseCore
import FirebaseAuth
import FirebaseFirestore
import FirebaseDatabase
import FirebaseStorage

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
Expand All @@ -15,9 +20,24 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
if let clientId = Bundle.main.object(forInfoDictionaryKey: "NMFClientId") as? String {
NMFAuthManager.shared().ncpKeyId = clientId
}
FirebaseApp.configure()
configureFirebaseEmulators()
return true
}

private func configureFirebaseEmulators() {
#if DEBUG
Auth.auth().useEmulator(withHost: "localhost", port: 9099)
let firestoreSettings = Firestore.firestore().settings
firestoreSettings.host = "localhost:8080"
firestoreSettings.isSSLEnabled = false
firestoreSettings.cacheSettings = MemoryCacheSettings()
Firestore.firestore().settings = firestoreSettings
Database.database().useEmulator(withHost: "localhost", port: 9000)
Storage.storage().useEmulator(withHost: "localhost", port: 9199)
#endif
}

// MARK: UISceneSession Lifecycle

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
Expand Down
99 changes: 99 additions & 0 deletions WhereAreYou/WhereAreYou/Data/FirebaseErrorMapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
//
// FirebaseErrorMapper.swift
// WhereAreYou
//
// Created by 이상유 on 2026-08-26.
//

import Foundation
import FirebaseAuth
import FirebaseFirestore
import FirebaseDatabase
import FirebaseStorage

/// Firebase NSError → AppError 변환기
enum FirebaseErrorMapper {

static func map(_ error: Error) -> AppError {
let nsError = error as NSError

switch nsError.domain {
case AuthErrorDomain:
return mapAuth(nsError)
case FirestoreErrorDomain:
return mapFirestore(nsError)
case "com.firebase.database":
return mapDatabase(nsError)
case StorageErrorDomain:
return mapStorage(nsError)
default:
return mapGeneral(nsError)
}
}

private static func mapAuth(_ error: NSError) -> AppError {
guard let code = AuthErrorCode(rawValue: error.code) else {
return .unknown(error)
}
switch code {
case .networkError:
return .network
case .userNotFound, .userTokenExpired, .invalidUserToken:
return .notAuthenticated
case .emailAlreadyInUse:
return .alreadyExists
default:
return .unknown(error)
}
}

private static func mapFirestore(_ error: NSError) -> AppError {
switch FirestoreErrorCode.Code(rawValue: error.code) {
case .notFound:
return .notFound
case .permissionDenied, .unauthenticated:
return .permissionDenied
case .alreadyExists:
return .alreadyExists
case .unavailable:
return .network
default:
return .unknown(error)
}
}

private static func mapDatabase(_ error: NSError) -> AppError {
// Realtime Database SDK는 public error code enum을 제공하지 않음
switch error.code {
case -4: // disconnected
return .network
case -3: // permission_denied
return .permissionDenied
default:
return .unknown(error)
}
}
Comment thread
sangYuLv marked this conversation as resolved.

private static func mapStorage(_ error: NSError) -> AppError {
switch StorageErrorCode(rawValue: error.code) {
case .objectNotFound:
return .notFound
case .unauthorized, .unauthenticated:
return .permissionDenied
case .quotaExceeded:
return .unknown(error)
case .retryLimitExceeded:
return .network
default:
return .unknown(error)
}
}

private static func mapGeneral(_ error: NSError) -> AppError {
if error.domain == NSURLErrorDomain {
return .network
}
return .unknown(error)
}

}
Loading
Loading