How to add Firebase Crashlytics in kotlin-only module? - android

I have a multi-module Android project. The Modules are: "app", "core", "auth", "coreAndroid", and various feature modules. I am trying to add Firebase Crashlytics to the "core" module that is kotlin-only, so that I can create a function like:
fun cLog(msg: String?){
FirebaseCrashlytics.getInstance().log(msg)
}
which will be accessed by all kotlin-only modules (like networking) to log error messages.
I have followed the official documentation but I can get the FirebaseCrashlytics Instance only in Android Modules. The google-services.json file is in the "app" module. I have been trying various solutions from the web for 3 days now but nothing seems to work.
The way that I have structured my gradle files is that I have an android-library-build.gradle and a library-build.gradle file, each of which act as a common ground for for their respective android and kotlin-only modules.
These are my gradle files:
(app) build.gradle.kts
plugins {
id("com.android.application")
kotlin("android")
kotlin("plugin.serialization") version Kotlin.version //"1.6.10"
kotlin("kapt")
id ("com.google.firebase.crashlytics")
id ("com.google.gms.google-services")
}
...
dependencies {
...
implementation (platform("com.google.firebase:firebase-bom:31.2.0"))
implementation ("com.google.firebase:firebase-analytics-ktx")
implementation ("com.google.firebase:firebase-crashlytics-ktx")
}
(project) build.gradle.kts
buildscript {
val kotlin_version by extra("1.8.0")
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
dependencies {
...
// Dependency for the Google services Gradle plugin
classpath("com.google.gms:google-services:4.3.15")
// Dependency for the Crashlytics Gradle plugin
classpath("com.google.firebase:firebase-crashlytics-gradle:2.9.4")
}
}
android-library-build.gradle
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'androidx.navigation.safeargs.kotlin'
...
dependencies {
...
implementation (platform("com.google.firebase:firebase-bom:31.2.0"))
implementation ("com.google.firebase:firebase-analytics-ktx")
implementation ("com.google.firebase:firebase-crashlytics-ktx")
}
library-build.gradle
apply plugin: 'java-library'
apply plugin: 'org.jetbrains.kotlin.jvm'
dependencies{
...
implementation (platform("com.google.firebase:firebase-bom:31.2.0"))
implementation ("com.google.firebase:firebase-analytics-ktx")
implementation ("com.google.firebase:firebase-crashlytics-ktx")
}
apply {
plugin("com.google.firebase.crashlytics")
plugin("com.google.gms.google-services")
}
(core) build.gradle.kts
apply {
from("$rootDir/library-build.gradle")
}
plugins {
kotlin(KotlinPlugins.serialization) version Kotlin.version
}
dependencies {
...
}
I have also tried:
to implement directly the dependencies and the plugins in the core build.gradle.kts file without success (with the platform implementation, and with the separate dependencies implementation).
to copy/paste the google-services.gson file in the core module
to use Firebase on Android without the google-services plugin meaning that I copy/pasted the generated strings from app/build/generated/res/google-services/debug/main/values/values.xml to the strings.xml file of app module, and deleted the gson file with the relevant plugins, and still didn't work.
I really can't figure it out. Any help would be deeply appreciated.

After the comments of #CommonsWare, it seems that its not possible to use directly the crashlytics library in a kotlin-only module.
I have found another way using an Interface in the koltin-only "core" module, and its implementation in the "app" module that has access to the crashlytics libraries.
Here is a simple example:
"core" module:
interface CrashlyticsService {
fun cLog(message: String?)
}
"app" module:
class FirebaseCrashlyticsService : CrashlyticsService {
override fun cLog(message: String?){
message?.let {
FirebaseCrashlytics.getInstance().log(it)
}
}
}
And then, wherever I want to use the cLog function in other modules that depend on "core" i just inject it in the constructor of the Class, i.e. :
class NetworkingServiceImpl(
private val httpClient: HttpClient,
private val crashlyticsService: CrashlyticsService
) : NetworkingService {
override suspend fun downloadVideo(videoUrl: String): ByteArray {
crashlyticsService.cLog("This is a crash test message")
return httpClient.get(videoUrl).body()
}
}

Related

Expected #AndroidEntryPoint to have a value. Did you forget to apply the Gradle Plugin?

When I am using Hilt in android with Room I got this kinda error.
The full log is here:
home/someone/Desktop/Calculator/app/build/tmp/kapt3/stubs/debug/com/hamidjonhamidov/calculator/MyApplication.java:7: error: [Hilt]
public class MyApplication extends android.app.Application {
^
Expected #HiltAndroidApp to have a value. Did you forget to apply the Gradle Plugin?
[Hilt] Processing did not complete. See error above for details./home/someone/Desktop/Calculator/app/build/tmp/kapt3/stubs/debug/com/hamidjonhamidov/calculator/ui/main/MainActivity.java:7: error: [Hilt]
Anyone knows solution for this?
I had this issue after upgrading Kotlin to 1.5.20.
Adding kapt.use.worker.api=false in gradle.properties worked for me the problem
Checkout dagger issue Support for Kotlin 1.5.20
Fortunately, there is simple solution.
In build.gradle in database scheme, we should use arguments += instead of arguments = .
defaultConfig{
javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}
Or/And in buld.gradle
You should apply plugin like:
apply plugin 'dagger.hilt.android.plugin'
This solved the problem)
UPDATE
Upgrade Hilt to v28.1.0 and Kotlin to v1.5.21 should fix this issue
OLD ANSWER
If you are on kotlin 1.5.20, answer of Mr-wil will decrease build speed as said in official doc:
To improve the speed of builds that use kapt, you can enable the
Gradle worker API for kapt tasks. Using the worker API lets Gradle run
independent annotation processing tasks from a single project in
parallel, which in some cases significantly decreases the execution
time.
Instead, set:
kapt {
javacOptions {
// These options are normally set automatically via the Hilt Gradle plugin, but we
// set them manually to workaround a bug in the Kotlin 1.5.20
option("-Adagger.fastInit=ENABLED")
option("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true")
}
}
source
This generic error message can also appear in many circumstances. As a more generic check, ensure that your module's build.gradle file, ensure that you has:
apply plugin: 'dagger.hilt.android.plugin'
at the top.
This was due to a bug in Kotlin 1.5.20. It is fixed in Kotlin 1.5.21.
So all you need to do is to upgrade to the latest version of Kotlin.
I had the same problem and it seems like there is a problem in kotlin-kapt plugin. If you guys have tried out all the above answers and didn't get resolved, please try the below code in your build.gradle(module-level) outside the dependencies{} block
kapt {
javacOptions {
option("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true")
}
}
in the build.gradle of your Android Gradle modules apply the plugin:
apply plugin: 'com.android.application'
apply plugin: 'dagger.hilt.android.plugin'
android {
// ...
}
see detail here
I'm still facing the same issue in 2022
I have solved the problem by adding
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38.1'
to build.gradle project and adding
id 'dagger.hilt.android.plugin'
to plugins in build.gradle app
In my case it solved by declaring plugin:
plugins {
id("dagger.hilt.android.plugin")
}
Check if all these are added.In my case I had missed adding one of the below line.
In project level build.gradle
buildscript {
dependencies {
classpath "com.google.dagger:hilt-android-gradle-plugin:2.44"
}
}
In app level build.gradle
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
dependencies {
implementation "com.google.dagger:hilt-android:2.44"
implementation "androidx.hilt:hilt-common:1.0.0"
kapt "com.google.dagger:hilt-android-compiler:2.44"
}
-In app level build.gradle---add the following in newer versions
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
In project level build.gradle
buildscript {
ext.kotlin_version = "1.7.21"
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.42'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

How to import firebase into a module other than the app module?

I want to make a multi module app with separate Data module. Can I import firebase in a plain kotlin module, and if not, how should I modify my Data module to be able to import firebase into it?
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.google.gms:google-services:4.3.2'
}
}
plugins {
id "org.jetbrains.kotlin.jvm"
}
dependencies {
def moduleDependencies = rootProject.ext.remoteDependencies
def moduleTestDependencies = rootProject.ext.remoteTestDependencies
implementation moduleDependencies.firestore
implementation moduleDependencies.firestoreKtx
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
apply plugin: 'com.google.gms.google-services'
This is my current build file inside my data module. Currently I am able to sync, and build, but I can't import firebase libraries inside the module.
Edit: The problem is that I want to use firestore inside a module other than the app module, but when I add the dependencies for it inside the data module, I can't use Firestore (because of unresolved reference)
The problem was that I tried to use firestore inside a pure kotlin library, to solve the problem I had to add:
apply plugin: 'com.android.library', and apply plugin: 'kotlin-android', and an android block to the gradle file of the module. (Basically I had to convert my kotlin library to an android library)

'Unresolved reference' errors for android library module referenced in app module

I have problems referencing my android library modules in my projects. Beside the main app module I use to have an android library module with either util stuff or as data module. I reference it in app module like that:
dependencies {
implementation project(":data")
}
When I build the project, it´s giving me lot of error messages 'Unresolved reference: ...' for all stuff that I reference in the app module to the android library module. But the IDE itself doesn´t have a problem, Intelligent finds all classes, interfaces etc., imports are fine, nothing is red. The android library module itself builds and creates aar-file in the output. It´s the compileDebugKotlin task that fails
Any general idea what may be related to that?
Found the problem, my android library module was missing the kotlin configuration:
apply plugin: 'kotlin-android'
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlinVersion:<version>"
}
Although I used kotlin .kt files in it, it could build without and also
Tools -> Kotlin -> 'Configure Kotlin in projects'
had told me 'All modules with Kotlin files are configured'
Your module's build.gradle file should have:
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
dependencies {
...
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
...
}
In my case It was apply plugin: 'kotlin-android',
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
and also added it on build.gradle
androidExtensions {
experimental = true
}
If it is a kotlin module make sure to add in its build.gradle file
apply plugin: 'kotlin'
I was using CoroutineWorkers and in my case I had to add work-runtime-ktx dependency to use it
implementation "androidx.work:work-runtime-ktx:2.4.0"

java.lang.ClassNotFoundException: Didn't find class "com.my.app.example.Main" on path: DexPathList

I'm having a hard time exactly what is causing this error on adb because I am using Kotlin, TornadoFX (a JavaFX Kotlin library) and Gluon with JFXMobile. When I use Gluon's androidInstall to build my project I encounter this error, along with a black screen:
java.lang.ClassNotFoundException: Didn't find class "com.my.app.example.Main" on path: DexPathList
I'm trying to use JavaFX 3D in this application, but I don't think that it's causing the error.
I checked my Android Manifest, and the package name is the same as my project.
My project hierarchy is like so:
root
libs
src
android
ios
main
kotlin
com.my.app.example
Main.kt
Which might be causing Android to not be able to find the file? Since there's no Java folder.
I have all of the following in my gradle file, compiled successfully:
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'java'
apply plugin: 'javafx-gradle-plugin'
apply plugin: 'org.javafxports.jfxmobile'
apply plugin: 'org.jetbrains.kotlin.android.extensions'
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
compile 'no.tornado:tornadofx:1.7.12'
compile 'no.tornado:tornadofx-android-compat:1.0.1'
compile 'com.gluonhq:charm:4.3.7'
compile fileTree(dir: 'libs', include: '*.jar')
}
The fileTree(dir: 'libs', include: '*.jar') is for an external library that I am using to import ObjModels for JavaFX, located in the libs folder of my project.
Things I am suspicious of causing this error:
Me not having the right things in my Gradle file because I am terrible with Gradle.
The .jar in my libs folder not being included correctly in the Android apk and messing it all up somehow
Kotlin file hierarchy somehow making Android not able to find the Main class, or the fact that it's Main.kt instead of Main.java
Please note that this project runs fine on my desktop, so it's not a problem with my source code, just something on the Android-specific end.
Any ideas what is causing this? Thanks for any help!
This is a very simple sample of a Gluon Mobile project working with Kotlin that can be deployed to Android/iOS.
Using the Gluon plugin for IntelliJ, created a project (Single View), and modify the build.gradle file:
build.gradle
buildscript {
ext.kotlin_version = '1.1.51'
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'org.javafxports:jfxmobile-plugin:1.3.9'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'java'
apply plugin: 'org.javafxports.jfxmobile'
apply plugin: 'org.jetbrains.kotlin.android.extensions'
repositories {
jcenter()
mavenCentral()
maven {
url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
}
}
mainClassName = 'com.gluon.kotlin.Main'
dependencies {
compile 'com.gluonhq:charm:4.4.1'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
compile 'no.tornado:tornadofx:1.7.12'
compile 'no.tornado:tornadofx-android-compat:1.0.1'
}
jfxmobile {
downConfig {
version = '3.6.0'
plugins 'display', 'lifecycle', 'statusbar', 'storage'
}
android {
manifest = 'src/android/AndroidManifest.xml'
}
ios {
infoPList = file('src/ios/Default-Info.plist')
forceLinkClasses = [
'com.gluonhq.**.*',
'javax.annotations.**.*',
'javax.inject.**.*',
'javax.json.**.*',
'org.glassfish.json.**.*'
]
}
}
Remove the /src/main/java package, and add the /src/main/kotlin one.
The Main.kt class is in /src/main/kotlin/com/gluon/kotlin/Main.kt:
Main.kt
package com.gluon.kotlin
import com.gluonhq.charm.glisten.application.MobileApplication
import com.gluonhq.charm.glisten.mvc.View
import com.gluonhq.charm.glisten.visual.MaterialDesignIcon
import javafx.geometry.Pos
import javafx.scene.control.Button
import javafx.scene.control.Label
import javafx.scene.layout.VBox
import tornadofx.plusAssign
class Main: MobileApplication() {
override fun init() {
addViewFactory(MobileApplication.HOME_VIEW, {
val view = View("home")
val vBox = VBox()
with (vBox) {
alignment = Pos.CENTER
spacing = 30.0
this += Button("Kotlin", MaterialDesignIcon.CODE.graphic()).apply {
println("Click")
}
this += Label("Gluon Mobile - Kotlin")
}
with(view) {
this.center = vBox
this.setOnShown {
with(MobileApplication.getInstance().appBar) {
this.navIcon = MaterialDesignIcon.MENU.button().apply {
println("Click")
}
this.titleText = "Gluon Mobile - Kotlin"
}
}
}
view
})
}
}
You can run the project on desktop, and without modifying the AndroidManifest file, deploy to an Android device using the androidInstall task.

InstantAppBundleException: No base split found! Base split APK is the one with no 'splitName' attribute set on the <manifest> tag

When trying to launch the Instant App, it reported
Side loading failed with message: Failure when trying to read bundel.
Failed to parse app: /data/local/tmp/aia/my_app.zip
When look at the logcat, it has this error
InstantAppBundleException: No base split found!
Base split APK is the one with no 'splitName' attribute set on the <manifest> tag
What did I miss?
I think you may have forgetten the baseFeature tag in your base module.
If you have a base module and 2 feature modules for examples your gradle should look like these (You need to pay attention to the correct plugins, the baseFeature=true tag and correct dependency declaration).
Base Module Gradle file:
apply plugin: 'com.android.feature'
android {
//this is mandatory for the base module of the project
baseFeature = true
...
}
dependencies {
...
feature project(':feature1')
feature project(':feature2')
application project(':hello-installed')
}
Feature1 module and Feature2 module Gradle files:
apply plugin: 'com.android.feature'
android {
...
}
dependencies {
...
implementation project(':base')
}
Instant App Module Gradle files:
apply plugin: 'com.android.instantapp'
dependencies {
implementation project(':base')
implementation project(':feature1')
implementation project(':feature2')
}
Full App Module Gradle files:
apply plugin: 'com.android.application'
android {
//classic gradle declaration for legacy apps
}
dependencies {
implementation project(':base')
implementation project(':feature1')
implementation project(':feature2')
//non instant libraries will only appear here
implementation project(':nonInstantLibrary')
}
Non Instant Compatible Module Gradle files:
//it will use the legacy library plugin
apply plugin: 'com.android.library'
dependencies {
...
implementation project(':base')
}

Categories

Resources