Skip to content

Commit fdf3dd5

Browse files
authored
Update README.md
1. Improvements and fix typos to the README.md file 2. Add the installation section
1 parent 8afdde1 commit fdf3dd5

File tree

1 file changed

+120
-20
lines changed

1 file changed

+120
-20
lines changed

README.md

Lines changed: 120 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,126 @@ The following libraries are available for the various Firebase products.
2929

3030
Is the Firebase library or API you need missing? [Create an issue](https://github.com/GitLiveApp/firebase-kotlin-sdk/issues/new?labels=API+coverage&template=increase-api-coverage.md&title=Add+%5Bclass+name%5D.%5Bfunction+name%5D+to+%5Blibrary+name%5D+for+%5Bplatform+names%5D) to request additional API coverage or be awesome and [submit a PR](https://github.com/GitLiveApp/firebase-kotlin-sdk/fork)
3131

32+
## Installation
33+
1. First of all, Add `plugin.serialization` plugin in gradle:
34+
* First go to `build.gradle.kts` in the main root folder and add it:
35+
36+
```groovy
37+
kotlin("plugin.serialization").version("1.9.20").apply(false) // use the latest version of kotlin
38+
```
39+
40+
* Then go to `build.gradle.kts` in the shared module:
41+
42+
```groovy
43+
kotlin("plugin.serialization")
44+
```
45+
2. Choose the Firebase products you are going to use, in this example, we will use only `firestore` but you can use more
46+
Start By adding the dependency `dev.gitlive:firebase-firestore` in the `commonMain` in the `sourceSets` block which exists usually in `kotlin` and you will find it in `build.gradle.kts` in the shared module:
47+
```groovy
48+
val commonMain by getting {
49+
dependencies {
50+
// ...
51+
implementation("dev.gitlive:firebase-firestore:1.10.0")
52+
}
53+
}
54+
```
55+
4. Create a Firebase project or use the one that you already have
56+
5. Add the Android and iOS apps and follow all the instructions
57+
6. Add the following to your `.gitignore` (optional):
58+
59+
```gitignore
60+
61+
# Google && Firebase for iOS and Android
62+
**/google-services.json
63+
**/GoogleService-Info.plist
64+
**/firebase_app_id_file.json
65+
66+
```
67+
68+
7. Setup Android and iOS apps in the Kotlin multiplatform project:
69+
### Android:
70+
Like usual in Android projects
71+
72+
* First, apply the `com.google.gms.google-services` gradle plugin in the `androidApp` or the Android module
73+
74+
Example of how it will look like:
75+
76+
```groovy
77+
plugins {
78+
kotlin("multiplatform")
79+
id("com.android.application")
80+
id("com.google.gms.google-services") version "4.4.0" // use latest version
81+
}
82+
```
83+
* Add the Firebase bom Android dependency:
84+
85+
86+
```groovy
87+
val androidMain by getting {
88+
dependencies {
89+
implementation(project.dependencies.platform("com.google.firebase:firebase-bom:32.5.0"))
90+
}
91+
}
92+
```
93+
94+
You don't have to add all the libraries you are going to use, like Firebase Firestore `com.google.firebase:firebase-firestore-ktx`
95+
because it's already there when you add the Firebase Firestore KMP SDK in the `commonMain`, but you can if you planning on using the code in the `androidMain` or `androidApp`
96+
97+
### iOS
98+
* You need to add the official [iOS Firebase SDK](https://firebase.google.com/docs/ios/setup) first, there a different ways to get it, check this [installation guide](https://firebase.google.com/docs/ios/installation-methods) but the easiest way is using swift package manager, you can also using `Cocoapods`
99+
* in `iOSApp.swift` or your main app file
100+
Import the Firebase Core
101+
```swift
102+
import SwiftUI
103+
import FirebaseCore
104+
```
105+
* Create `AppDelegate` that initializes the Firebase iOS SDK using
106+
```swift
107+
FirebaseApp.configure()
108+
```
109+
and add it to your app
110+
111+
example of what it will look like:
112+
113+
```swift
114+
import SwiftUI
115+
import FirebaseCore
116+
117+
class AppDelegate: NSObject, UIApplicationDelegate {
118+
func application(_ application: UIApplication,
119+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
120+
FirebaseApp.configure()
121+
122+
return true
123+
}
124+
}
125+
126+
@main
127+
struct iOSApp: App {
128+
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
129+
var body: some Scene {
130+
WindowGroup {
131+
ContentView()
132+
}
133+
}
134+
}
135+
136+
```
137+
138+
32139
## Kotlin-first design
33140
34-
Unlike the Kotlin Extensions for the Firebase Android SDK this project does not extend a Java based SDK so we get the full power of Kotlin including coroutines and serialization!
141+
Unlike the Kotlin Extensions for the Firebase Android SDK, this project does not extend a Java-based SDK so we get the full power of Kotlin including coroutines and serialization!
35142
36143
<h3><a href="https://kotlinlang.org/docs/tutorials/coroutines/async-programming.html#coroutines">Suspending functions</a></h3>
37144
38-
Asynchronous operations that return a single or no value are represented by suspending functions in the SDK instead of callbacks, listeners or OS specific types such as [Task](https://developer.android.com/reference/com/google/android/play/core/tasks/Task), for example:
145+
Asynchronous operations that return a single or no value are represented by suspending functions in the SDK instead of callbacks, listeners, or OS-specific types such as [Task](https://developer.android.com/reference/com/google/android/play/core/tasks/Task), for example:
39146
40147
```kotlin
41148
suspend fun signInWithCustomToken(token: String): AuthResult
42149
```
43150

44-
It is important to remember that unlike a callback based API, wating for suspending functions to complete is implicit and so if you don't want to wait for the result you can `launch` a new coroutine:
151+
It is important to remember that, unlike a callback-based API, waiting for suspending functions to complete is implicit so if you don't want to wait for the result you can `launch` a new coroutine:
45152

46153
```kotlin
47154
//TODO don't use GlobalScope
@@ -58,24 +165,17 @@ Asynchronous streams of values are represented by Flows in the SDK instead of re
58165
val snapshots: Flow<DocumentSnapshot>
59166
```
60167

61-
The flows are cold, which means a new listener is added every time a terminal operator is applied to the resulting flow. A buffer with the [default size](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-channel/-b-u-f-f-e-r-e-d.html) is used to buffer values received from the listener, use the [`buffer` operator](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/buffer.html) on the flow to specify a user-defined value and to control what happens when data is produced faster than consumed, i.e. to control the back-pressure behavior. Often you are only interested in the latest value received, in this case you can use the [`conflate` operator](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/conflate.html) to disable buffering.
168+
The flows are cold, which means a new listener is added every time a terminal operator is applied to the resulting flow. A buffer with the [default size](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-channel/-b-u-f-f-e-r-e-d.html) is used to buffer values received from the listener, use the [`buffer` operator](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/buffer.html) on the flow to specify a user-defined value and to control what happens when data is produced faster than consumed, i.e. to control the back-pressure behavior. Often you are only interested in the latest value received, in this case, you can use the [`conflate` operator](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/conflate.html) to disable buffering.
62169

63170
The listener is removed once the flow [completes](https://kotlinlang.org/docs/reference/coroutines/flow.html#flow-completion) or is [cancelled](https://kotlinlang.org/docs/reference/coroutines/flow.html#flow-cancellation).
64171

65172
<h3><a href="https://github.com/Kotlin/kotlinx.serialization">Serialization</a></h3>
66173

67174
The official Firebase SDKs use different platform-specific ways to support writing data with and without custom classes in [Cloud Firestore](https://firebase.google.com/docs/firestore/manage-data/add-data#custom_objects), [Realtime Database](https://firebase.google.com/docs/database/android/read-and-write#basic_write) and [Functions](https://firebase.google.com/docs/functions/callable).
68175

69-
The Firebase Kotlin SDK uses Kotlin serialization to read and write custom classes to Firebase. To use Kotlin serialization in your project add the plugin to your gradle file:
70-
71-
```groovy
72-
plugins {
73-
kotlin("multiplatform") version "1.8.20" // or kotlin("jvm") or any other kotlin plugin
74-
kotlin("plugin.serialization") version "1.8.20"
75-
}
76-
```
176+
The Firebase Kotlin SDK uses Kotlin serialization to read and write custom classes for Firebase. To use Kotlin serialization in your project, follow the instructions in the installation for the Kotlin serialization
77177

78-
Then mark you custom classes `@Serializable`:
178+
Then mark your custom classes `@Serializable`:
79179

80180
```kotlin
81181
@Serializable
@@ -88,7 +188,7 @@ Instances of these classes can now be passed [along with their serializer](https
88188
db.collection("cities").document("LA").set(City.serializer(), city, encodeDefaults = true)
89189
```
90190

91-
The `encodeDefaults` parameter is optional and defaults to `true`, set this to false to omit writing optional properties if they are equal to theirs default values.
191+
The `encodeDefaults` parameter is optional and defaults to `true`, set this to false to omit writing optional properties if they are equal to their default values.
92192
Using [@EncodeDefault](https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization/-encode-default/) on properties is a recommended way to locally override the behavior set with `encodeDefaults`.
93193

94194
You can also omit the serializer but this is discouraged due to a [current limitation on Kotlin/JS and Kotlin/Native](https://github.com/Kotlin/kotlinx.serialization/issues/1116#issuecomment-704342452)
@@ -129,7 +229,7 @@ val document = PointOfInterest(
129229

130230
<h4>Polymorphic serialization (sealed classes)</h4>
131231

132-
This sdk will handle polymorphic serialization automatically if you have a sealed class and its children marked as `Serializable`. It will include a `type` property that will be used to discriminate which child class is the serialized.
232+
This SDK will handle polymorphic serialization automatically if you have a sealed class and its children are marked as `Serializable`. It will include a `type` property that will be used to discriminate which child class is serialized.
133233

134234
You can change this `type` property by using the `@FirebaseClassDiscrminator` annotation in the parent sealed class:
135235

@@ -204,15 +304,15 @@ In cases where it makes sense, such as Firebase Functions HTTPS Callable, operat
204304

205305
## Multiplatform
206306

207-
The Firebase Kotlin SDK provides a common API to access Firebase for projects targeting *iOS*, *Android* and *JS* meaning you can use Firebase directly in your common code. Under the hood, the SDK achieves this by binding to the respective official Firebase SDK for each supported platform.
307+
The Firebase Kotlin SDK provides a common API to access Firebase for projects targeting *iOS*, *Android*, and *JS* meaning you can use Firebase directly in your common code. Under the hood, the SDK achieves this by binding to the respective official Firebase SDK for each supported platform.
208308

209309
It uses the <a href="https://github.com/GitLiveApp/firebase-java-sdk">Firebase Java SDK</a> to support the JVM target.
210310

211311
### Accessing the underlying Firebase SDK
212312

213-
In some cases you might want to access the underlying official Firebase SDK in platform specific code, for example when the common API is missing the functionality you need. For this purpose each class in the SDK has `android`, `ios` and `js` properties which holds the equivalent object of the underlying official Firebase SDK.
313+
In some cases, you might want to access the underlying official Firebase SDK in platform-specific code, for example when the common API is missing the functionality you need. For this purpose, each class in the SDK has `android`, `ios`, and `js` properties which hold the equivalent object of the underlying official Firebase SDK.
214314

215-
These properties are only accessible from the equivalent target's source set. For example to disable persistence in Cloud Firestore on Android you can write the following in your Android specific code (e.g. `androidMain` or `androidTest`):
315+
These properties are only accessible from the equivalent target's source set. For example, to disable persistence in Cloud Firestore on Android you can write the following in your Android-specific code (e.g. `androidMain` or `androidTest`):
216316

217317
```kotlin
218318
Firebase.firestore.android.firestoreSettings = FirebaseFirestoreSettings.Builder(Firebase.firestore.android.firestoreSettings)
@@ -224,6 +324,6 @@ These properties are only accessible from the equivalent target's source set. Fo
224324
If you'd like to contribute to this project then you can fork this repository.
225325
You can build and test the project locally.
226326
1. Open the project in IntelliJ IDEA.
227-
2. Install cocoapods via `sudo gem install -n /usr/local/bin cocoapods`
327+
2. Install Cocoapods via `sudo gem install -n /usr/local/bin cocoapods`
228328
3. Install the GitLive plugin into IntelliJ
229-
4. After a gradle sync then run `publishToMavenLocal`
329+
4. After a gradle sync run `publishToMavenLocal`

0 commit comments

Comments
 (0)