Skip to content

Conversation

@vincentborko
Copy link
Contributor

Thank you for contributing to the Skip project! Please use this space to describe your change and add any labels (bug, enhancement, documentation, etc.) to help categorize your contribution.

Firestore test doesnt pass for Kotlin (12/11 passed) but I didnt touch Firestore

Skip Pull Request Checklist:

  • REQUIRED: I have signed the Contributor Agreement
  • REQUIRED: I have tested my change locally with swift test
  • OPTIONAL: I have tested my change on an iOS simulator or device
  • OPTIONAL: I have tested my change on an Android emulator or device

@cla-bot cla-bot bot added the cla-signed label Jan 11, 2026
@vincentborko vincentborko changed the title Functions fix Functions fix + add crashlytics log Jan 11, 2026

// MARK: - Kotlin to Swift type conversion helpers (from SkipFirebaseFirestore)

fileprivate func deepSwift(value: Any) -> Any {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about harmonizing with SkipFirestore by moving its similar deepSwift implementation:

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<Any, Any> {
return deepSwift(map: map)
} else if let collection = value as? kotlin.collections.Collection<Any> {
return deepSwift(collection: collection)
} else {
return value
}
}

... into SkipFirebaseCore.swift? That way we would share the same implementation for both Functions and Firestore…

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll give it a try, hope I won't run into merge conflicts this time

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to move Timestamp into Core then as well

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to move Timestamp into Core then as well

I think that's fine, since it is a core type for Firebase.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we somehow "reimport" this in skipfirestore? I noticed now to access Timestamps we need to import SkipFirebaseCore + skipfirebasefirestore for android, while only firestore for iOS

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, right … that is a problem. We don't currently handle @_exported import … imports, and so anything defined in SkipFirebaseCore won't come in automatically when importing the other two packages.

Maybe you could add a public typealias Timestamp = SkipFirebaseCore.Timestamp in each of SkipFirebaseFirestore.swift and SkipFirebaseFunction.swift to work around this for the time being?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…and if that does't work out, we can always just go back to duplicating the deepSwift logic in both packages.

}
}

public func deepSwift<T>(map: kotlin.collections.Map<T, Any>) -> Dictionary<T, Any> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think only the top deepSwift(value: Any) function needs to be public. These other ones can be private.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of course, fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, seeing a CI failure:

e: file:///Users/runner/work/skip-firebase/skip-firebase/.build/plugins/outputs/skip-firebase/SkipFirebaseFirestore/destination/skipstone/SkipFirebaseFirestore/src/main/kotlin/skip/firebase/firestore/SkipFirebaseFirestore.kt:1041:20 Cannot access 'fun <T> deepSwift(map: Map<T, Any>): Dictionary<T, Any>': it is private in file.
e: file:///Users/runner/work/skip-firebase/skip-firebase/.build/plugins/outputs/skip-firebase/SkipFirebaseFirestore/destination/skipstone/SkipFirebaseFirestore/src/main/kotlin/skip/firebase/firestore/SkipFirebaseFirestore.kt:1080:20 Cannot access 'fun <T> deepSwift(map: Map<T, Any>): Dictionary<T, Any>': it is private in file.
e: file:///Users/runner/work/skip-firebase/skip-firebase/.build/plugins/outputs/skip-firebase/SkipFirebaseFirestore/destination/skipstone/SkipFirebaseFirestore/src/main/kotlin/skip/firebase/firestore/SkipFirebaseFirestore.kt:1041:20 Cannot access 'fun <T> deepSwift(map: Map<T, Any>): Dictionary<T, Any>': it is private in file.

Copy link
Contributor Author

@vincentborko vincentborko Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, for e.g. in querydocumentsnapshot in skipfirestore we need

override public func data() -> [String: Any] {
    if let data = doc.getData() {
        return deepSwift(map: data)
    } else {
        return [:]
    }
}

I'll make them internal, agree?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh it looks like Kotlin's internal might work file-level instead of module-scoped? I guess I have to revert to public, tests are failing with internal as well...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that'll be fine.

@marcprux
Copy link
Member

Thanks! One last request, can you add typealiases for Timestamp in SkipFirebaseFirestore.swift‎ and SkipFirebaseFunctions.swift like:

public typealias Timestamp = SkipFirebaseCore.Timestamp

That way, if anyone was relying on getting Timestamp by importing SkipFirebaseFirestore, it should continue to work for them without having the explicitly import SkipFirebaseCore.

@marcprux
Copy link
Member

Thanks for this!

@marcprux marcprux changed the title Functions fix + add crashlytics log Support deep type conversions in FirebaseFunctions data and add crashlytics log function Jan 16, 2026
@marcprux marcprux merged commit 845c9fd into skiptools:main Jan 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants