Android FirebaseMessaging - getToken fails for some users - android

I have the following setup in my grade files:
project:
classpath 'com.google.gms:google-services:4.3.10'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
app:
implementation platform('com.google.firebase:firebase-bom:29.0.0')
// When using the BoM, you don't specify versions in Firebase library dependencies
implementation 'com.google.firebase:firebase-crashlytics'
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-messaging'
After the users logs in, I'm doing
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(task -> {
String refreshToken = task.getResult();
....
}
which is fine for most users, but for some (not only a few) get errors like FIS_AUTH_ERROR, MISSING_INSTANCEID_SERVICE, SERVICE_NOT_AVAILABLE.
I guess (!), MISSING_INSTANCEID_SERVICE is no Google API on the device, SERVICE_NOT_AVAILABLE missing network (?) but I'm not sure at all. And I have absolutely no clue about the FIS_AUTH_ERROR. Is there some documentation about this?

MISSING_INSTANCEID_SERVICE
Tokens can't be generated.
SERVICE_NOT_AVAILABLE
The device cannot read the response, or there was a server error.
FIS_AUTH_ERROR
you need to check the documentation get token and get id methods had changed
I think it has to do with firebase dependencies versions mismatch. Try to import the BoM for the Firebase platform. By using BoM your app will always use compatible versions of the Firebase Android libraries.
dependencies {
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:30.0.2')
// .... }

FIS_AUTH_ERROR suggests, that the local installation cannot be authenticated:
Firebase Cloud Messaging uses Firebase installation IDs to target devices for message delivery.
Source: Manage Firebase installations
It's a little difficult, unless having a device available, which would show this issue - or somehow being able to narrow this down - by hardware vendor, Android version or package version - because "some (not only a few)" is relatively meaningless, from a technical perspective.
It could well be, that the SHA1/SHA265 key fingerprint might have been changed (you should know) and "some (not only a few)" might still haven't updated to the latest version of the APK/AAB package, signed with the new signing key. Crashlytics would show the package version. You could add the old SHA1/SHA265 key fingerprint back in, so that their instances could authenticate again.

Related

Full offline option using AWS DataStore and then allow an optional activation for the the cloud sync features in Android

I've started a project using AwsAppsync.
The app is going to be offline first. And we want to offer the option to sync in the cloud as an extra option later if the customer wants it. So, I configured my project like this:
In build.gradle added the following:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.2'
classpath 'com.amplifyframework:amplify-tools-gradle-plugin:0.2.1'
}
}
apply plugin: 'com.amplifyframework.amplifytools'
And added those dependencies:
implementation 'com.amplifyframework:core:0.10.0'
implementation 'com.amplifyframework:aws-api:0.10.0' // If using cloud sync
implementation 'com.amplifyframework:aws-datastore:0.10.0'
And then using the Amplify CLI:
copy
Generate models at any time by executing this Amplify CLI command:
amplify codegen models
After this in the onCreate of the activity:
ModelProvider modelProvider = AmplifyModelProvider.getInstance();
Amplify.addPlugin(AWSDataStorePlugin.forModels(modelProvider));
Amplify.configure(getApplicationContext());
With this i can Query, update and delete the data.
Is this enough for a full offline experience?
Now, based on the documentation, to add online sync feature, I have to do the following:
Using the Amplify CLI:
amplify push
This will create the amplifyconfiguration.json with the sync configuration.
Now, this information seems to be set in build time. So, how can I enable/disable this feature to be used just when I need it? The documentation mention the following:
ModelProvider modelProvider = AmplifyModelProvider.getInstance();
Amplify.addPlugin(AWSDataStorePlugin.forModels(modelProvider));
Amplify.addPlugin(new AWSApiPlugin()); // If using remote model synchronization
Amplify.configure(getApplicationContext());
So, would be adding that "new AWSApiPlugin()" the only thing I need to do to enable/disable this feature? Thanks!
Any tutorial/book good enough to explain this? I've read several documentation(including the official) and I wasn't able to find something about this particular case. It is always with online sync from the get go.
From a high level, yes this is fairly accurate. DataStore doesn't require a backend it will just work as a local DB of sorts that you can use for offline including queries. When you add in a backend with amplify push (this deploys an AppSync API backed by DynamoDB) and connect it with AWSApiPlugin it will begin syncing. The best tutorial is in the docs: https://docs.amplify.aws

FirebaseRemoteConfig Error "No value of type 'String' exists for parameter key"

I am using Firebase Core and some other Features, but not Remote Config. Multiple times a second the following Output is on Logcat.
Where can I disable the Remote Config functionality or even set those non-existing values?
Dependencies:
// Project
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.google.gms:google-services:4.2.0'
classpath 'com.google.firebase:firebase-plugins:1.2.0'
classpath 'io.fabric.tools:gradle:1.26.1'
// Module
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:support-vector-drawable:28.0.0'
implementation 'com.android.support:preference-v7:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'org.jsoup:jsoup:1.11.3'
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.google.firebase:firebase-core:16.0.8'
implementation 'com.google.firebase:firebase-messaging:17.5.0'
implementation 'com.google.firebase:firebase-perf:16.2.4'
implementation 'com.google.android.gms:play-services-location:16.0.0'
implementation 'com.jsibbold:zoomage:1.2.0'
implementation 'com.android.support:exifinterface:28.0.0'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
W/FirebaseRemoteConfig: No value of type 'String' exists for parameter key 'sessions_max_length_minutes'.
W/FirebaseRemoteConfig: No value of type 'String' exists for parameter key 'sessions_max_length_minutes'.
W/FirebaseRemoteConfig: No value of type 'String' exists for parameter key 'sessions_feature_enabled'.
W/FirebaseRemoteConfig: No value of type 'String' exists for parameter key 'sessions_max_length_minutes'.
W/FirebaseRemoteConfig: No value of type 'String' exists for parameter key 'fpr_vc_trace_sampling_rate'.
W/FirebaseRemoteConfig: No value of type 'String' exists for parameter key 'sessions_feature_enabled'.
W/FirebaseRemoteConfig: No value of type 'String' exists for parameter key 'fpr_vc_trace_sampling_rate'.
It is not causing any problems I think, just annoying that it spams the Console.
Firebase answer to my bug report:
It seems that you're getting some warning about Remote Config. We managed to reproduce on our end, and our engineers have confirmed that this is working as intended. This happens because the Performance Monitoring SDK was added on your app. This is because Performance Monitoring uses Firebase Remote Config internally. However, our engineers have confirmed that they will try to reduce these warnings in the future. For now, you can ignore these as it's only a warning, and should not affect the app's performance.
It comes from last versions of firebase-perf (for example, 16.2.5), because it has internal firebase-remote-config dependency.
I have the same issue, but I don't know how to properly fix this log spam (except "Fold lines like this" option in logcat).
I hope Firebase team will fix it soon.
Solution
Firebase Performance released version 19.0.8 last week to address log spam issue. (see Release Note https://firebase.google.com/support/release-notes/android#2020-07-17) You can update your dependency com.google.firebase:firebase-perf to be the same or higher version to validate the fix.
Explaination
To explain more about the reason of this issue: Firebase Performance utilizes Firebase Remote Config to sample down number of events being sent to Firebase, so it will call Firebase Remote Config API getValue(String key) every time it needs the sampling configuration value.
However, Firebase Remote Config fetch happens every 12 hours. It is possible that configuration value doesn't exist by the time of development. In this case, Firebase Performance SDK will use default value.
When the configuration value doesn't exist, Firebase Remote Config will generate this log for warning, which is the source of log spam for Firebase Performance users. (See Source Code)
We have reduced Firebase Performance's call frequency to Firebase Remote Config to avoid triggering this log.
If you use Firebase Console, setting both values in the Remote Config tab stops the warnings.
I've used: (as string values)
Parameter key: sessions_max_length_minutes | Value: "15"
Parameter key: sessions_feature_enabled | Value: "true"
Not sure if there are any side effects, but (hopefully) it's an internal testing thing and doesn't change anything.
Firebase Performance Monitoring uses Firebase Remote Config internally. You can't change the output, but you can send feedback to the team using the link that I gave in the comment above.
The Firebase Android library firebase-core is no longer needed. This
SDK included the Firebase SDK for Google Analytics.
Remove firebase-core in your build.gradle
This might be related to, or a result of:
W/zzd: Application name is not set. Call Builder#setApplicationName
disabling perf-plugin & firebase-perf removes the annoying log entries:
// classpath "com.google.firebase:perf-plugin:1.2.1"
// apply plugin: "com.google.firebase.firebase-perf"
// implementation "com.google.firebase:firebase-perf:17.0.0"
firebase-config works fine on it's own.
This was my observation:
If you have a specific key set up on RemoteConfig console & have not added a default key in the default xml (passed in setDefaultsAsync()).
And if, for some rare case,
either the there was No Connectivity or Firebase RemoteConfig failed to fetch the values & if that specific key was used to get a default value,
you might get that message in the Logcat.

io.grpc.StatusRuntimeException: UNAUTHENTICATED: Credentials require channel with PRIVACY_AND_INTEGRIY

I am using Dialogflow Java Client library in my android app, to run the detect intent API as given in below link.
https://github.com/dialogflow/dialogflow-java-client-v2/blob/master/samples/src/main/java/com/example/dialogflow/DetectIntentTexts.java
I modified the code given in above link slightly to authenticate the client first before sending the detect intent request. My sample code is as follows:
SessionsSettings sessionsSettings = SessionsSettings.newBuilder().setCredentialsProvider(credentialsProvider).build();
SessionsClient sessionsClient = SessionsClient.create(sessionsSettings);
SessionName session = SessionName.of(PROJECT_ID, sessionId);
System.out.println("Session Path: " + session.toString());
TextInput.Builder textInput = TextInput.newBuilder().setText(text).setLanguageCode(langCode);
QueryInput queryInput=QueryInput.newBuilder().setText(textInput).build();
DetectIntentResponse response = sessionsClient.detectIntent(session, queryInput);
where
CredentialsProvider credentialsProvider = new CredentialsProvider() {
#Override
public Credentials getCredentials() throws IOException {
InputStream fileStream = appContext.getApplicationContext().getAssets().open("MyDialogflowProject-4cxxxxx.json");
return ServiceAccountCredentials.fromStream(fileStream);
}
};
But I get the following error
com.google.api.gax.rpc.UnauthenticatedException:
io.grpc.StatusRuntimeException: UNAUTHENTICATED: Credentials require
channel with PRIVACY_AND_INTEGRITY security level. Observed security
level: NONE
at com.google.api.gax.rpc.ApiExceptionFactory.createException(ApiExceptionFactory.java:73)
Can anyone please tell how to set the Security Level for SessionSettings in this case ?
Try to update library versions you are using. On transport layer Security Level should be setup.
For example gradle dependencies from my hello world project which is working with dialogflow v2:
dependencies {
compile ("com.google.api.grpc:proto-google-common-protos:1.12.0")
compile ("io.grpc:grpc-netty:1.14.0")
compile ("io.grpc:grpc-protobuf:1.14.0")
compile ("io.grpc:grpc-stub:1.14.0")
compile ("com.google.auth:google-auth-library-oauth2-http:0.10.0")
compile ("com.google.cloud:google-cloud-storage:1.38.0")
compile ("io.netty:netty-tcnative-boringssl-static:2.0.12.Final")
compile ("com.google.cloud:google-cloud-dialogflow:0.55.1-alpha")
}
In my case, I have found out that I have set the IntelliJ environment variable to FIRESTORE_EMULATOR_HOST=localhost:8080 to use the Firebase emulators in the past.
Later I tried to push data to Cloud Firestore without removing that variable, but the attempts were unsuccessful with the error PRIVACY_AND_INTEGRITY.
After some time, I found the localhost setting and removed it. Once removed, I was able to push the data to the cloud without any issues.

firebase Instance ID vs android Instance ID

Play services API suggests that there is something called Instance ID
However, after including the following in Android Studio, I am unable to import InstanceID class
compile "com.google.android.gms:play-services-identity:${googlePlayServicesVersion}"
compile "com.google.android.gms:play-services-auth:${googlePlayServicesVersion}"
Per this SO Post, InstanceID class should work if I include the identity play services library.
Following conversion of google cloud messaging to firebase cloud messaging, I believe, it must have been replaced by Firebase Instance ID as mentioned in the red message here.
Now I am not sure if using Firebase ID should have indeed "replaced" Instance ID.
Or, maybe I am missing some library which includes InstanceID?
Yap,
I had the issue, and finally I realize that InstanceID class is a part of 'com.google.android.gms:play-services-iid' library , so you just have to add this line in your gradle build file:
compile "com.google.android.gms:play-services-iid:${googlePlayServicesVersion}"
Unless this works for me :) ...

Firebase and Fabric Integration: No detectable Fabric Event in Firebase

I have integrated my Firebase and Fabric projects since it's available few days ago.
I have such kind of fabric events tracking configured in my code:
Answers.getInstance().logCustom(new CustomEvent("Entity Click").putCustomAttribute("domain", entity.getDomain()).putCustomAttribute("entity", entity.entityId));
But in my Firebase console under Analytics -> Events and Analytics -> StreamView, I can't seem to see Fabric events get integrated over. All I can see is the normal generic Firebase events:
ad_click
ad_impression
app_clear_data
app_remove
app_update
first_open
os_update
screen_view
session_start
Did I misunderstand something?
UPDATE:
Portion of my build.gradle file:
classpath 'io.fabric.tools:gradle:1.24.4'
compile('com.crashlytics.sdk.android:crashlytics:2.7.1#aar') {
transitive = true;
}
#I did not use firebase-core
compile 'com.google.firebase:firebase-config:11.6.0'
compile 'com.google.firebase:firebase-ads:11.6.0'
compile 'com.google.firebase:firebase-messaging:11.6.0'
UPDATE 2:
In Fabric Console, Tools -> Firebase shows the linking in green:
UPDATE 3:
I'm using the new Firebase UI. Under Spark Plan, did not currently link to Big Query.
I did not really pay attention to my firebase events the past few days. But this morning I integrated my Firebase project over to Google Analytics at https://analytics.google.com in hope to gain some missing features like city/state level real-time location info. Turns out there's nothing new and it's the same info that I can find from Firebase Console. But when I check out the Events tab, I can now see my Fabric events. I then headed back to Firebase Console, and found my fabric events are showing now.
It could be the Analytics triggered the integration, or could have already populated in my Firebase prior to any of this. Either way, it's working for me now. :)

Categories

Resources