kotlin realm demo canot be run - realm

kotlin version 1.0.0,realm version 0.88.0-SNAPSHOT
I download realm kotlin demo ,and run
if code like this:
var person = Person()
person.id = 1
person.name = "Young Person"
person.age = 14
realm.beginTransaction()
realm.copyToRealm(person)
realm.commitTransaction()
throw Exception: Caused by: java.lang.ClassCastException: io.realm.examples.kotlin.model.Person cannot be cast to io.realm.PersonRealmProxyInterface
else I change code like this:
realm.beginTransaction()
// Add a person
var person = realm.createObject(Person::class.java)
person.id = 1
person.name = "Young Person"
person.age = 14
// When the transaction is committed, all changes a synced to disk.
realm.commitTransaction()
then realm insert a data but person.name ,id,age is empty value or 0;
how to solve it

With Realm 0.88.0-SNAPSHOT you have to use their Gradle Plugin as well. If you Google this exception (realm java.lang.ClassCastException ProxyInterface) you will find this Github Issue - 2353 which says:
We just merged our byte code weaver into master, and it sounds like it isn't being triggered in your case. Note that from 0.88.0-SNAPSHOT you have to use our Gradle plugin: https://realm.io/news/android-installation-change/
Previously you would install Realm like:
repositories {
jcenter()
}
dependencies {
compile 'io.realm:realm-android:<version>'
}
Now you must install it to also include the Gradle plugin:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.realm:realm-gradle-plugin:<version>"
}
}
apply plugin: 'realm-android'
So that byte code weaving is turned on. Without this, you receive an error exactly like your first use case (which was correct code, but for the snapshot release you chose to use, you also needed this extra step of the Gradle plugin). There are other important notes in the link above, along with the release notes for changes in recent versions of Realm.

Related

Why do I get "Unresolved reference: platform" when using the firebase-bom dependency with KMM

When I attempt to add the Firebase-bom dependency using the following block in a Kotlin Multiplatform Mobile (KMM) project's shared module, the word platform appears in red error text and the Gradle build fails with "Unresolved reference: platform." How can I resolve this so it builds correctly?
val androidMain by getting {
dependencies {
implementation(platform("com.google.firebase:firebase-bom:28.0.1"))
implementation("com.google.firebase:firebase-analytics-ktx")
}
}
The answer lies in KT-40489.
The platform() function used to import the Firebase Bill of Materials is not available in Kotlin Multiplatform plugin’s KotlinDependencyHandler but only in Gradle’s standard DependencyHandler. It also does not seem that a fix is coming soon. As a result, you need to specify Gradle's handler explicitly.
Here are two workarounds:
val androidMain by getting {
dependencies {
implementation(project.dependencies.platform("..."))
}
}
OR
val androidMain by getting {
dependencies {
"jvmMainImplementation"(platform("...))
}
}

Distributing APK splits with Firebase App Distribution

“Is it possible to use Firebase App Distribution with APK split? It doesn't declare a dependency on assemble task, are there any workarounds for this?"
The problem with the gradle plugin is that it
doesn't declare dependency on assemble task (in general, regardless of apk splits, by gradle convention, you shouldn't just "expect" the apks to be there)
doesn't generate tasks per apk splits -- but you do for flavors
Try the following work around:
// Generate firebase app distribution task variants for all abis
applicationVariants.all { variant ->
variant.outputs.all { output ->
def abi = output.getFilter(com.android.build.OutputFile.ABI)
if (abi == null) return
def abiName = abi.replace("_", "").replace("-", "")
task("appDistributionUpload${abiName.capitalize()}${variant.name.capitalize()}", type: com.google.firebase.appdistribution.gradle.UploadDistributionTask_Decorated) {
appDistributionProperties = new com.google.firebase.appdistribution.gradle.AppDistributionProperties(
new com.google.firebase.appdistribution.gradle.AppDistributionExtension(),
project,
variant
)
appDistributionProperties.apkPath = output.outputFile.absolutePath
appDistributionProperties.serviceCredentialsFile = project.file("secrets/ci-firebase-account.json")
appDistributionProperties.releaseNotes = abi
appDistributionProperties.groups = "ra-testers"
// Add dependsOn respective assemble task, so it actually
// builds apk it wants to upload, not just expect it to be there
dependsOn "assemble${variant.name.capitalize()}"
}
}
}

Errors in adding firebase to flutter in android studio on Mac OS: Plugin project :firebase_core_web not found. Please update settings.gradle [duplicate]

I try to connect Android project to Firebase but I get this error as I added the following to pubsec.yaml:
firebase_auth: ^0.16.0
cloud_firestore: ^0.13.5
when I gradle run and it is not working
Plugin project :firebase_core_web not found. Please update settings.gradle.
Plugin project :firebase_auth_web not found. Please update settings.gradle.
Plugin project :cloud_firestore_web not found. Please update settings.gradle.
Is there any solution for it
In your android/app/build.gradle, update the following:
android {
// ...
defaultConfig {
// ...
minSdkVersion 16
}
}
into:
android {
// ...
defaultConfig {
// ...
minSdkVersion 23
}
}
Note:
You need to use minSdkVersion 23 when using firebase in flutter.
From the docs:
By default, Flutter supports Android SDK v16 (Jelly Bean, released 2012), but multidex doesn't really work with Jelly Bean (though, it's possible). Configuring Jelly Bean to work is beyond the scope of this codelab, so we'll change the minimum target SDK version from v16 to v21 (Lollipop, released 2014).
To change the minimum target SDK version:
Open android/app/build.gradle, then find the line that says minSdkVersion 16.
Change that line to minSdkVersion 21.
Save the file.
After upgrading, it should work fine. The settings.gradle file is provided to you when you create any new flutter project. For reference, this is how your settings.gradle file should be (default file no changes):
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
https://github.com/PeterHdd/Firebase-Flutter-tutorials/blob/master/firebase_storage_tutorial/android/settings.gradle
Explanation of settings.gradle:
Gradle is a build tool used for android projects, just like ant or maven, it uses groovy language or kotlin for scripting. In this case the above code is written using groovy and since groovy is a jvm language then it is able to use Java libraries. So basically include ':app' will add the project to the build(in groovy you can omit parenthesis for a method).
This line:
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
is getting the path to the flutter project that you created in your machine. For reference:
https://docs.gradle.org/current/javadoc/org/gradle/api/initialization/ProjectDescriptor.html#getProjectDir--
https://docs.oracle.com/javase/8/docs/api/java/io/File.html#toPath--
https://docs.oracle.com/javase/7/docs/api/java/util/Properties.html
This line:
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
Will create an empty file called .flutter-plugins, under the root of your flutter project. Then plugins.each{ name, path -> this is basically an iteration that will add the plugin name and the path of the plugin to the file .flutter_plugins, if the plugin is not found in that file you get the error in this question
.flutter-plugins file:
# This is a generated file; do not edit or check into version control.
cloud_firestore=/Users/<users>/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/
cloud_firestore_web=/Users/<users>/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/
firebase_auth=/Users/<users>/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/
firebase_auth_web=/Users/<users>/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.2/
firebase_core=/Users/<users>/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.4+3/
firebase_core_web=/Users/<users>/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/
firebase_database=/Users/<users>/.pub-cache/hosted/pub.dartlang.org/firebase_database-3.1.5/
firebase_storage=/Users/<users>/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.5/
Change file settings.gradle to this
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
Please add this in flutter app -> android -> settings.gradle
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
My settings worked with the following versions.
pubspec.yaml
firebase_auth: ^0.14.0+5
cloud_firestore: ^0.12.9+5
I also added (pubspec.yaml) to silence the warnings.
firebase_core: ^0.4.5
firebase_analytics: ^5.0.2
build.gradle (root dir)
classpath 'com.google.gms:google-services:4.3.3'
build.gradle (app dir)
minSdkVersion 23
targetSdkVersion 28
Then I added this at the bottom of build.gradle
apply plugin: 'com.google.gms.google-services'
The final thing is to run the Terminal command:
$flutter packages get
After building the project - you wait 15 seconds and it will show a "Congratulations, you've successfully added Firebase to your app!" message on your Firebase Console.
Just make the
minSdkVersion 21
In the addition to Peter's answer
I misplaces this line. The correct one is the bottom of the file
apply plugin: 'com.google.gms.google-services'
JUST add this to your settings.gradle file -
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
This could be one of the dependencies version is not matching. Please make sure your are using all latest versions of lib in your pubspec.yaml
You can refer the latest version of dependencies from
PubDev
I got the same errors:-
Plugin project :firebase_core_web not found. Please update settings.gradle.
Plugin project :cloud_fireenter code heresenter code heretore_web not found. Please update settings.gradle.
Plugin project :firebasenter code heree_auth_web not found. Please update settings.gradle.
I resolved this by following process:-
Go to your app level gradle file and see there targetSdkVersion, if it has 16 or less then update to new latest version serching from this link https://developer.android.com/guide/topics/manifest/uses-sdk-element. It will be helpful.

How do you restore private NuGet packages from private VSTS feeds with Cake

I have a task which restores our NuGet package for our dotnet core application:
Task("Restore-Packages")
.Does(() =>
{
DotNetCoreRestore(sln, new DotNetCoreRestoreSettings {
Sources = new[] {"https://my-team.pkgs.visualstudio.com/_packaging/my-feed/nuget/v3/index.json"},
Verbosity = DotNetCoreVerbosity.Detailed
});
});
However when run on VSTS it errors with the following:
2018-06-14T15:10:53.3857512Z C:\Program Files\dotnet\sdk\2.1.300\NuGet.targets(114,5): error : Unable to load the service index for source https://my-team.pkgs.visualstudio.com/_packaging/my-feed/nuget/v3/index.json. [D:\a\1\s\BitCoinMiner.sln]
2018-06-14T15:10:53.3857956Z C:\Program Files\dotnet\sdk\2.1.300\NuGet.targets(114,5): error : Response status code does not indicate success: 401 (Unauthorized). [D:\a\1\s\BitCoinMiner.sln]
How do I authorize access for the build agent to our private VSTS?
I literally just had this same problem, apparently the build agents in VSTS can't get to your private VSTS feed without an access token so you are going to have to create a Personal Access Token in VSTS and provide that to the built in Cake method to add an authenticated VSTS Nuget feed as one of the sources. Here, I have wrapped it in my own convenience Cake method that checks to see if the package feed is already present, if not, then it adds it:
void SetUpNuget()
{
var feed = new
{
Name = "<feedname>",
Source = "https://<your-vsts-account>.pkgs.visualstudio.com/_packaging/<yournugetfeed>/nuget/v3/index.json"
};
if (!NuGetHasSource(source:feed.Source))
{
var nugetSourceSettings = new NuGetSourcesSettings
{
UserName = "<any-odd-string>",
Password = EnvironmentVariable("NUGET_PAT"),
Verbosity = NuGetVerbosity.Detailed
};
NuGetAddSource(
name:feed.Name,
source:feed.Source,
settings:nugetSourceSettings);
}
}
and then I call it from the "Restore" task:
Task("Restore")
.Does(() => {
SetUpNuget();
DotNetCoreRestore("./<solution-name>.sln");
});
Personally, I prefer to keep PATs away from the source control so here I am reading from env vars. In VSTS you can create an environment variable under the Variables tab of your CI build configuration.
Hope this helps! Here is a link to Cake's documentation.
As pointed out by both #KevinSmith and #NickTurner, a better approach to accessing the VSTS feed is by using the pre-defined system variable System.AccessToken as opposed to using limited validity, manually created and cumbersome PATs. This variable is available on the build agents for the current build to use. More info here.
One way of using this token in the Cake script is as follows:
First, expose the system variable as an environment variable for the Cake task in azure-pipelines.yml
steps:
- task: cake-build.cake.cake-build-task.Cake#0
displayName: 'Cake '
inputs:
target: Pack
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
Then in Cake you can access it like you would any environment variable, so in my case:
if (!NuGetHasSource(source:feed.Source))
{
Information($"Nuget feed {feed.Source} not found, adding...");
var nugetSourceSettings = new NuGetSourcesSettings
{
UserName = "whoosywhatsit",
Password = EnvironmentVariable("SYSTEM_ACCESSTOKEN"),
Verbosity = NuGetVerbosity.Detailed
};
NuGetAddSource(
name:feed.Name,
source:feed.Source,
settings:nugetSourceSettings);
}
This seems to work! If there are better approaches of accessing this variable in Cake please let me know. Please also note in my case, I am only using this to restore packages from my VSTS feed, not for pushing to it. That I do via a DotNetCoreCLI#2 task in the YML like so:
- task: DotNetCoreCLI#2
displayName: 'dotnet nuget push'
inputs:
command: push
packagesToPush: 'artifacts/package.nupkg'
publishVstsFeed: '<id of my VSTS feed>'
And Azure pipeline handles the rest.

Cleanest way in Gradle to get the path to a jar file in the gradle dependency cache

I'm using Gradle to help automate Hadoop tasks. When calling Hadoop, I need to be able to pass it the path to some jars that my code depends on so that Hadoop can send that dependency on during the map/reduce phase.
I've figured out something that works, but it feels messy and I'm wondering if there's a feature I'm missing somewhere.
This is a simplified version of my gradle script that has a dependency on the solr 3.5.0 jar, and a findSolrJar task that iterates through all of the jar files in the configuration to find the right one:
apply plugin: 'groovy'
repositories {
mavenCentral()
}
dependencies {
compile 'org.apache.solr:solr-solrj:3.5.0'
}
task findSolrJar() {
println project.configurations.compile*.toURI().find { URI uri -> new File(uri).name == 'solr-solrj-3.5.0.jar'}
}
running this gives me output like this:
gradle findSolrJar
file:/Users/tnaleid/.gradle/caches/artifacts-8/filestore/org.apache.solr/solr-solrj/3.5.0/jar/74cd28347239b64fcfc8c67c540d7a7179c926de/solr-solrj-3.5.0.jar
:findSolrJar UP-TO-DATE
BUILD SUCCESSFUL
Total time: 2.248 secs
Is there a better way to do this?
Your code can be simplified a bit, for example project.configurations.compile.find { it.name.startsWith("solr-solrj-") }.
You can also create a dedicated configuration for an artifact, to keep it clean; and use asPath if the fact that it can potentially return several locations works well for your use case (happens if it resolves same jar in several locations):
configurations {
solr
}
dependencies {
solr 'org.apache.solr:solr-solrj:3.5.0'
}
task findSolrJars() {
println configurations.solr.asPath
}
To avoid copy-paste, in case you as well need that jar in compile configuration, you may add this dedicated configuration into compile one, like:
dependencies {
solr 'org.apache.solr:solr-solrj:3.5.0'
compile configurations.solr.dependencies
}
I needed lombok.jar as a java build flag to gwt builds this worked great !
configurations {
lombok
}
dependencies {
lombok 'org.projectlombok:lombok+'
}
ext {
lombok = configurations.lombok.asPath
}
compileGwt {
jvmArgs "-javaagent:${lombok}=ECJ"
}
I was surprised that the resolution worked early enough in the configuraiton phase, but it does.
Here is how I did it:
project.buildscript.configurations.classpath.each {
String jarName = it.getName();
print jarName + ":"
}
I recently had this problem as well. If you are building a java app, the problem at hand is normally that want to get the group:module (groupId:artifactId) to path-to-jar mapping (i.e. the version is not a search criteria as in one app there is normally only one version of each specific jar).
In my gradle 5.1.1 (kotlin-based) gradle build I solved this problem with:
var spec2File: Map<String, File> = emptyMap()
configurations.compileClasspath {
val s2f: MutableMap<ResolvedModuleVersion, File> = mutableMapOf()
// https://discuss.gradle.org/t/map-dependency-instances-to-file-s-when-iterating-through-a-configuration/7158
resolvedConfiguration.resolvedArtifacts.forEach({ ra: ResolvedArtifact ->
s2f.put(ra.moduleVersion, ra.file)
})
spec2File = s2f.mapKeys({"${it.key.id.group}:${it.key.id.name}"})
spec2File.keys.sorted().forEach({ it -> println(it.toString() + " -> " + spec2File.get(it))})
}
The output would be some like:
:jing -> /home/tpasch/scm/db-toolchain/submodules/jing-trang/build/jing.jar
:prince -> /home/tpasch/scm/db-toolchain/lib/prince-java/lib/prince.jar
com.github.jnr:jffi -> /home/tpasch/.gradle/caches/modules-2/files-2.1/com.github.jnr/jffi/1.2.18/fb54851e631ff91651762587bc3c61a407d328df/jffi-1.2.18-native.jar
com.github.jnr:jnr-constants -> /home/tpasch/.gradle/caches/modules-2/files-2.1/com.github.jnr/jnr-constants/0.9.12/cb3bcb39040951bc78a540a019573eaedfc8fb81/jnr-constants-0.9.12.jar
com.github.jnr:jnr-enxio -> /home/tpasch/.gradle/caches/modules-2/files-2.1/com.github.jnr/jnr-enxio/0.19/c7664aa74f424748b513619d71141a249fb74e3e/jnr-enxio-0.19.jar
After that, it is up to you to do something useful with this Map. In my case I add some --path-module options to my Java 11 build like this:
val patchModule = listOf(
"--patch-module", "commons.logging=" +
spec2File["org.slf4j:jcl-over-slf4j"].toString(),
"--patch-module", "org.apache.commons.logging=" +
spec2File["org.slf4j:jcl-over-slf4j"].toString()
)
patchModule.forEach({it -> println(it)})
tasks {
withType<JavaCompile> {
doFirst {
options.compilerArgs.addAll(listOf(
"--release", "11",
"--module-path", classpath.asPath
) + patchModule)
// println("Args for for ${name} are ${options.allCompilerArgs}")
}
}
}

Resources