All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.plusmobileapps.firebase.auth.ApiClient.kt Maven / Gradle / Ivy

Go to download

A kotlin multiplatform mobile library for authenticating with Firebase for Android, iOS, and JVM

The newest version!
package com.plusmobileapps.firebase.auth

import com.plusmobileapps.firebase.auth.model.network.ApiErrorResponse
import com.plusmobileapps.firebase.auth.model.network.ApiResponse
import com.plusmobileapps.firebase.auth.model.network.models.ChangePasswordModel
import com.plusmobileapps.firebase.auth.model.network.models.DeleteUserDTO
import com.plusmobileapps.firebase.auth.model.network.models.GetUserDataModel
import com.plusmobileapps.firebase.auth.model.network.models.IdTokenModel
import com.plusmobileapps.firebase.auth.model.network.models.SendPasswordResetModel
import com.plusmobileapps.firebase.auth.model.network.models.SignInModel
import com.plusmobileapps.firebase.auth.model.network.models.SignUpModel
import com.plusmobileapps.firebase.auth.model.network.safeRequest
import io.ktor.client.HttpClient
import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.logging.LogLevel
import io.ktor.client.plugins.logging.Logging
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.client.request.url
import io.ktor.http.ContentType
import io.ktor.http.HttpMethod
import io.ktor.http.contentType
import io.ktor.serialization.kotlinx.json.json
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json
import kotlin.coroutines.CoroutineContext

internal expect fun createHttpClientEngine(): HttpClientEngine

internal interface ApiClient {
    suspend fun signIn(request: SignInModel.Request): ApiResponse
    suspend fun signUp(request: SignUpModel.Request): ApiResponse

    suspend fun getAccessToken(request: IdTokenModel.Request): ApiResponse
    suspend fun forgotPassword(request: SendPasswordResetModel.Request): ApiResponse
    suspend fun changePassword(request: ChangePasswordModel.Request): ApiResponse
    suspend fun deleteAccount(request: DeleteUserDTO.Request)
    suspend fun getUserData(request: GetUserDataModel.Request): ApiResponse

}

internal class ApiClientImpl(
    engine: HttpClientEngine,
    private val apiKey: String,
    private val ioContext: CoroutineContext
) : ApiClient {

    private val httpClient: HttpClient = HttpClient(engine) {
        expectSuccess = true
        install(ContentNegotiation) {
            json(Json {
                isLenient = true
                prettyPrint = true
                ignoreUnknownKeys = true
            })
        }
        install(Logging) {
            level = LogLevel.ALL
            this.logger = object : io.ktor.client.plugins.logging.Logger {
                override fun log(message: String) {
                    println(message)
                }
            }
        }
    }

    override suspend fun signIn(request: SignInModel.Request): ApiResponse =
        withContext(ioContext) {
            httpClient.safeRequest {
                method = HttpMethod.Post
                contentType(ContentType.Application.Json)
                url(SignInModel.getUrl(apiKey))
                setBody(
                    mapOf(
                        "email" to request.email,
                        "password" to request.password,
                        "returnSecureToken" to true.toString()
                    )
                )
            }
        }

    override suspend fun signUp(
        request: SignUpModel.Request,
    ): ApiResponse =
        withContext(ioContext) {
            httpClient.safeRequest {
                method = HttpMethod.Post
                contentType(ContentType.Application.Json)
                url(SignUpModel.getUrl(apiKey))
                setBody(
                    mapOf(
                        "email" to request.email,
                        "password" to request.password,
                        "returnSecureToken" to true.toString()
                    )
                )
            }
        }

    override suspend fun getAccessToken(request: IdTokenModel.Request): ApiResponse =
        withContext(ioContext) {
            httpClient.safeRequest {
                method = HttpMethod.Post
                url(IdTokenModel.getUrl(apiKey))
                contentType(ContentType.Application.Json)
                setBody(
                    mapOf(
                        "grant_type" to request.grant_type,
                        "refresh_token" to request.refresh_token,
                    )
                )
            }
        }


    override suspend fun forgotPassword(request: SendPasswordResetModel.Request): ApiResponse =
        withContext(ioContext) {
            httpClient.safeRequest {
                method = HttpMethod.Post
                url(SendPasswordResetModel.getUrl(apiKey))
                contentType(ContentType.Application.Json)
                setBody(
                    mapOf(
                        "requestType" to request.requestType,
                        "email" to request.email,
                    )
                )
            }
        }

    override suspend fun changePassword(request: ChangePasswordModel.Request): ApiResponse =
        withContext(ioContext) {
            httpClient.safeRequest {
                method = HttpMethod.Post
                url(ChangePasswordModel.getUrl(apiKey))
                contentType(ContentType.Application.Json)
                setBody(
                    mapOf(
                        "idToken" to request.idToken,
                        "password" to request.password,
                        "returnSecureToken" to request.returnSecureToken.toString(),
                    )
                )
            }
        }

    override suspend fun deleteAccount(request: DeleteUserDTO.Request) {
        withContext(ioContext) {
            httpClient.post(DeleteUserDTO.getUrl(apiKey)) {
                contentType(ContentType.Application.Json)
                setBody(
                    mapOf(
                        "idToken" to request.idToken
                    )
                )
            }
        }
    }

    override suspend fun getUserData(request: GetUserDataModel.Request): ApiResponse =
        withContext(ioContext) {
            httpClient.safeRequest {
                method = HttpMethod.Post
                url(GetUserDataModel.getUrl(apiKey))
                contentType(ContentType.Application.Json)
                setBody(
                    mapOf(
                        "idToken" to request.idToken
                    )
                )
            }
        }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy