diff --git a/Sources/SkipFirebaseCore/SkipFirebaseCore.swift b/Sources/SkipFirebaseCore/SkipFirebaseCore.swift index bc3f310..ab29429 100644 --- a/Sources/SkipFirebaseCore/SkipFirebaseCore.swift +++ b/Sources/SkipFirebaseCore/SkipFirebaseCore.swift @@ -140,5 +140,89 @@ public final class FirebaseOptions { } } +// https://firebase.google.com/docs/reference/swift/firebasefirestore/api/reference/Classes/Timestamp +// https://firebase.google.com/docs/reference/android/com/google/firebase/Timestamp + +public class Timestamp: Hashable, KotlinConverting { + public let timestamp: com.google.firebase.Timestamp + + public init(timestamp: com.google.firebase.Timestamp) { + self.timestamp = timestamp + } + + public init(date: Date) { + self.timestamp = com.google.firebase.Timestamp(date.kotlin()) + } + + public init(seconds: Int64, nanoseconds: Int32) { + self.timestamp = com.google.firebase.Timestamp(seconds, nanoseconds) + } + + // SKIP @nooverride + public override func kotlin(nocopy: Bool = false) -> com.google.firebase.Timestamp { + timestamp + } + + public var description: String { + timestamp.toString() + } + + public static func == (lhs: Self, rhs: Self) -> Bool { + lhs.timestamp == rhs.timestamp + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(timestamp.hashCode()) + } + + public func dateValue() -> Date { + Date(platformValue: timestamp.toDate()) + } + + public func toDate() -> Date { + dateValue() + } + + public var seconds: Int64 { + timestamp.seconds + } + + public var nanoseconds: Int32 { + timestamp.nanoseconds + } +} + +// MARK: - Kotlin to Swift type conversion helpers + +public func deepSwift(value: Any) -> Any { + if let str = value as? String { + return str // needed to not be treated as a Collection + } else if let ts = value as? com.google.firebase.Timestamp { + return Timestamp(timestamp: ts) + } else if let map = value as? kotlin.collections.Map { + return deepSwift(map: map) + } else if let collection = value as? kotlin.collections.Collection { + return deepSwift(collection: collection) + } else { + return value + } +} + +public func deepSwift(map: kotlin.collections.Map) -> Dictionary { + var dict = Dictionary() + for (key, value) in map { + dict[key] = deepSwift(value: value) + } + return dict +} + +public func deepSwift(collection: kotlin.collections.Collection) -> Array { + var array = Array() + for value in collection { + array.append(deepSwift(value: value)) + } + return array +} + #endif #endif diff --git a/Sources/SkipFirebaseCrashlytics/SkipFirebaseCrashlytics.swift b/Sources/SkipFirebaseCrashlytics/SkipFirebaseCrashlytics.swift index fc90b14..d3feac3 100644 --- a/Sources/SkipFirebaseCrashlytics/SkipFirebaseCrashlytics.swift +++ b/Sources/SkipFirebaseCrashlytics/SkipFirebaseCrashlytics.swift @@ -21,6 +21,10 @@ public final class Crashlytics { // public static func crashlytics(app: FirebaseApp) -> Crashlytics { // Crashlytics(crashlytics: com.google.firebase.crashlytics.FirebaseCrashlytics.getInstance(app.app)) // } + + public func log(_ message: String) { + _crashlytics.log(message) + } } #endif #endif diff --git a/Sources/SkipFirebaseFirestore/SkipFirebaseFirestore.swift b/Sources/SkipFirebaseFirestore/SkipFirebaseFirestore.swift index 34ac908..5f8c93a 100644 --- a/Sources/SkipFirebaseFirestore/SkipFirebaseFirestore.swift +++ b/Sources/SkipFirebaseFirestore/SkipFirebaseFirestore.swift @@ -5,6 +5,8 @@ import Foundation import SkipFirebaseCore import kotlinx.coroutines.tasks.await +public typealias Timestamp = SkipFirebaseCore.Timestamp + public final class Firestore: KotlinConverting { public let store: com.google.firebase.firestore.FirebaseFirestore @@ -957,55 +959,6 @@ public class DocumentReference: KotlinConverting { - public let timestamp: com.google.firebase.Timestamp - - public init(timestamp: com.google.firebase.Timestamp) { - self.timestamp = timestamp - } - - public init(date: Date) { - self.timestamp = com.google.firebase.Timestamp(date.kotlin()) - } - - public init(seconds: Int64, nanoseconds: Int32) { - self.timestamp = com.google.firebase.Timestamp(seconds, nanoseconds) - } - - // SKIP @nooverride - public override func kotlin(nocopy: Bool = false) -> com.google.firebase.Timestamp { - timestamp - } - - public var description: String { - timestamp.toString() - } - - public static func == (lhs: Self, rhs: Self) -> Bool { - lhs.timestamp == rhs.timestamp - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(timestamp.hashCode()) - } - - public func dateValue() -> Date { - Date(platformValue: timestamp.toDate()) - } - - public func toDate() -> Date { - dateValue() - } - - public var seconds: Int64 { - timestamp.seconds - } - - public var nanoseconds: Int32 { - timestamp.nanoseconds - } -} - public class WriteBatch { public let batch: com.google.firebase.firestore.WriteBatch @@ -1102,37 +1055,5 @@ fileprivate func asNSError(firestoreException: com.google.firebase.firestore.Fir return NSError(domain: FirestoreErrorDomain, code: firestoreException.code.value(), userInfo: userInfo) } -// MARK: Utilies for converting between Swift and Kotlin types - -fileprivate func deepSwift(value: Any) -> Any { - if let str = value as? String { - return str // needed to not be treated as a Collection - } else if let ts = value as? com.google.firebase.Timestamp { - return Timestamp(timestamp: ts) - } else if let map = value as? kotlin.collections.Map { - return deepSwift(map: map) - } else if let collection = value as? kotlin.collections.Collection { - return deepSwift(collection: collection) - } else { - return value - } -} - -fileprivate func deepSwift(map: kotlin.collections.Map) -> Dictionary { - var dict = Dictionary() - for (key, value) in map { - dict[key] = deepSwift(value: value) - } - return dict -} - -fileprivate func deepSwift(collection: kotlin.collections.Collection) -> Array { - var array = Array() - for value in collection { - array.append(deepSwift(value: value)) - } - return array -} - #endif #endif diff --git a/Sources/SkipFirebaseFunctions/SkipFirebaseFunctions.swift b/Sources/SkipFirebaseFunctions/SkipFirebaseFunctions.swift index 266a5d2..8925ab9 100644 --- a/Sources/SkipFirebaseFunctions/SkipFirebaseFunctions.swift +++ b/Sources/SkipFirebaseFunctions/SkipFirebaseFunctions.swift @@ -5,6 +5,8 @@ import Foundation import SkipFirebaseCore import kotlinx.coroutines.tasks.await +public typealias Timestamp = SkipFirebaseCore.Timestamp + // https://firebase.google.com/docs/reference/swift/firebasefunctions/api/reference/Classes/Functions // https://firebase.google.com/docs/reference/android/com/google/firebase/functions/FirebaseFunctions @@ -86,11 +88,19 @@ public class HTTPSCallableResult: KotlinConverting Any { + guard let rawData = platformValue.getData() else { + return [String: Any]() } + // Convert Kotlin collections to Swift types (same approach as Firestore) + return deepSwift(value: rawData) } }