OneSignal Notifications not appearing in Xamarin Forms Android - Release Mode - firebase

I'm using OneSignal SDK for notifications with Xamarin Forms - when I run the app in Debug mode, the notifications arrive on the device.
However, when compiling and running in Release mode, no notifications appear on the device (Android One).
I suspect maybe something is being stripped out (by the compiler / linker?) - but I'm not sure how to resolve this.
The app runs in Release mode, however, in some cases seems to crash and the logs indicate the following:
java.lang.ClassNotFoundException: Didn't find class "com.onesignal.GcmBroadcastReceiver" on path: DexPathList.......
androidx.core.app.CoreComponentFactory.instantiateReceiver
java.lang.InstantiationException: java.lang.Class<com.google.firebase.iid.FirebaseInstanceIdReceiver> cannot be instantiated
androidx.core.app.CoreComponentFactory.instantiateService
java.lang.InstantiationException: java.lang.Class<com.onesignal.RestoreKickoffJobService> cannot be instantiated

This type of message is caused by ProGuard / R8. You can disable it or you can add specific rules to the Proguard.cfg file to prevent code from being stripped out.

For others that may be seeing the same issue this is what fixed it for me:
Create an empty file in the Android project proguard.cfg. Set the build action to ProguardConfiguration
Add the following
-keep class com.onesignal.** { *; }
-keep class com.google.firebase.** { *; }
Re-build and redeploy.

Related

CrossFirebasePushNotification.Current.RegisterForPushNotifications(); throwing NullReference iOS

to do push notifications in my Xamarin Forms App, I am using the CrossGeeks FirebasePushNotification Plugin. My android setup is working alright, but for the iOS app, when I try to run the app, the line
CrossFirebasePushNotification.Current.RegisterForPushNotifications();
is causing a NullReference Exception. What I have done to set up:
Set "FirebaseAppDelegateProxyEnabled" to "No"
Changed the GoogleService plist to Bundle Resource
Added the FirebasePushNotificationManager.Initialize(options, true); in the App Delegate (and it is saying it is unreachable?"
I am testing on a simulator but I believe this should only prevent the receiving of notifications, not the registering?
How would I solve this problem? In the documentation, it states that these are the steps needed for iOS setup.

Unity Firebase Crashlytics not sending any crash reports, getting "failed to retrieve settings" error on logcat

Unity editor version: 2019.3.15f1
Firebase Unity SDK version: firebase_unity_sdk_6.15.2
Additional SDKs im using: Unity IAP, Gamesparks, Ironsource, Facebook, Appsflyer, GameAnalytics
Platform im using the Unity editor on: Windows
Platform im targeting: Android
Scripting Runtime: IL2CPP
Problem
I am getting data on firebase analytics, but I cannot get crashlytics to report anything. Im stuck on this...
Steps to reproduce:
Add the firebase analytics and crashlytics sdks.
Add the google-services.json GoogleService-Info.plist files somewhere in assets folder
Add this code to initialise the firebase
// Use this for initialization
void Start ()
{
// Initialize Firebase
Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
var dependencyStatus = task.Result;
if (dependencyStatus == Firebase.DependencyStatus.Available)
{
// Create and hold a reference to your FirebaseApp,
// where app is a Firebase.FirebaseApp property of your application class.
// Crashlytics will use the DefaultInstance, as well;
// this ensures that Crashlytics is initialized.
Firebase.FirebaseApp app = Firebase.FirebaseApp.DefaultInstance;
// Set a flag here for indicating that your project is ready to use Firebase.
VisualDebugger.SetText("crashlytics initialised");
}
else
{
UnityEngine.Debug.LogError(System.String.Format(
"Could not resolve all Firebase dependencies: {0}",dependencyStatus));
VisualDebugger.SetText("crashlytics NOT initialised: " + dependencyStatus);
// Firebase Unity SDK is not safe to use here.
}
});
Invoke("IsCrashEnabled", 5f);
}
void IsCrashEnabled()
{
VisualDebugger.AddLine("IsCrashlyticsCollectionEnabled: "+Firebase.Crashlytics.Crashlytics.IsCrashlyticsCollectionEnabled);
}
In order to get the app to run with the facebook sdk installed Ive added these two lines to proguard-user.txt
-keep public class com.facebook.**{public *; }
-keep public class com.facebook.internal.**{ public *; }
and commented out the following lines from mainTemplate.gradle
//implementation 'com.android.support:appcompat-v7:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
//implementation 'com.android.support:customtabs:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
//implementation 'com.android.support:support-v4:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
When I run the app, firebase is initialised successfully. Also Firebase.Crashlytics.Crashlytics.IsCrashlyticsCollectionEnabled returns true.
I crash the app in a number of different ways, then open it again without reinstalling. But no crash reports are sent.
When I watch logcat when starting the app I see this error from firebase each time the app is opened
2020-09-28 16:18:59.332 25773-25847/? E/FirebaseCrashlytics: Failed to retrieve settings from https://firebase-settings.crashlytics.com/spi/v2/platforms/android/gmp/REDACTEDblahblahblah/settings
Update Oct 19, 2020:
Today a developer updated the issue I linked in this answer saying the Firebase team fixed a backend bug last Friday (Oct 16) that was affecting some new Unity Android apps registering w/ Firebase - likely the bug behind your issue. I had already solved the issue in my own project using the below solution, but if you haven't yet updated your project, I recommend running it again and seeing if Crashlytics is working for you now..
I've been dealing with the same issue this week in Unity 2019.4.11f1 - i see the same error message about not being able to retrieve settings, but with my specific project and appIds in the URL.
I found a solution in this Github issue, which suggests the problem is caused by the version of an android library that is a dependency for the Unity Firebase Crashlytics package. My rough understanding is that the firebase-crashlytics-unity library is a wrapper around android library firebase:firebase-crashlytics, and the unity package allows the underlying native Android code to be used from Unity. Version com.google.firebase:firebase-crashlytics:17.10.0 has issues with getting the settings for some Firebase projects on Android. Myself and several others following this issue found forcing Unity to use this specific dependency at version 17.1.1 resolved the issue.
Someone else with the same issue in the thread contacted Firebase support and was told:
The error you are seeing "Failed to retrieve settings" is related to
the SDK version being used. If you go to "Assets > Firebase > Editor>
CrashlyticsDependencies" you can manually update the SDK to point to
the latest Crashlytics SDK version 17.2.2. Please give it a try and if
you continue having issues, let me know.
It turned out this advice wasn't quite right - some of us following the thread then experienced a different issue when using the Android Crashlytics SDK version 17.2.2 with Unity crashlytics version 6.16.0. So I'd specifically recommend trying out the below suggestion or other solutions in the thread to set your Android crashlytics library to v17.1.1.
Changes I made in my project to address this:
First, I updated my unity firebase packages in the package manager to use version 6.16.0. In my project 4 packages were installed - core, analytics, crashlytics, and messaging.
Then I searched for the the Crashlytics package's dependency file - Crashlytics-Dependencies.xml (found by searching project - was in /Library/PackageCache/com.google.firebase.crashlytics#6.16.0/Firebase/Editor/ for me). This file initally had "com.google.firebase:firebase-crashlytics:17.0.0" listed, which I updated to be: "com.google.firebase:firebase-crashlytics:17.1.1".
As an extra precaution, I also added created a MyProject-Dependencies.xml file, as was suggested by a user in the thread - this file also specifies version "com.google.firebase:firebase-crashlytics:17.1.1".
Next, I modified the Unity build process to use a custom mainTemplate.gradle file to specify dependencies,
rather than using the External Dependency Resolver to manage and
embed unity packages (option in Build Settings > PlayerSettings >
Android).
I also updated the settings on the External Dependency Manager Android Ressolver:
Disabled AutoResolve and Disabled Resolve on Build (we dont want EDM updating dependencies without our knowledge when building)
I also turned disabled AndroidPackageInstallationEnabled - this has made the resolution process much faster and removed a bunch of .aar files from the android dependencies list, and hasn't caused any problems in my project.
I then ran External Dependency Resolver > Android > Force Resolve, which after the settings changes above, should now embed a list of the dependencies for the Android build into the mainTemplate.gradle file - Check this file (its in Assets/Plugins/Android) and you should now see com.google.firebase:firebase-crashlytics:17.1.1 in that list.
Also, I recommend reading this article about managing Unity Firebase dependencies from one of the Firebase developer advocates, Patrick Martin. It helped me wrap my head around how Android dependency management in Unity works, as well as how the Android gradle build process works.

Flutter access database in background fetch on Android

I am trying to access the local database on the device while the app is completely closed, to achieve this I am using the sqlite plugin sqflite: ^1.2.0 and the background fetch plugin background_fetch: ^0.4.0.
I am able to register the headless background task with no issues, its when I try to run the background tasks, I get the following error!
The plugins seems to work fine while the app is running, or put into background mode.
Any suggestions please?
Error
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method getDatabasesPath on channel com.tekartik.sqflite)
Flutter version:
Flutter 1.12.13+hotfix.7 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 9f5ff2306b (11 days ago) • 2020-01-26 22:38:26 -0800
Engine • revision a67792536c
Tools • Dart 2.7.0
Flutter Doctor
[✓] Flutter (Channel stable, v1.12.13+hotfix.7, on Mac OS X 10.15.2 19C57, locale en-GB)
[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 11.3)
[✓] Android Studio (version 3.5)
[✓] Connected device (1 available)
• No issues found!
You can try looking at sqflite troubleshooting section on their Github page, especially the one related to your error. Let me paste the bits from that page here.
This error is typically a build/setup error after adding the dependency.
Try all the steps defined at the top of the documents
Make sure you stop the current running application if any
Force a flutter packages get
Try to clean your build folder flutter clean
On iOS, you can try to force a pod install / pod update
Search for other bugs in flutter like this, other people face the same issue with other plugins so it is likely not sqflite related
Advanced checks:
Check the GeneratedPluginRegistrant file that flutter run should have generated in your project contains a line registering the plugin.
Android:
SqflitePlugin.registerWith(registry.registrarFor("com.tekartik.sqflite.SqflitePlugin"));
iOS:
[SqflitePlugin registerWithRegistrar:[registry registrarForPlugin:#"SqflitePlugin"]];
Check MainActivity.java (Android) contains a call to GeneratedPluginRegistrant asking it to register itself. This call should be made from the app launch method (onCreate).
public class MainActivity extends FlutterActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
}
}
Check AppDelegate.m (iOS) contains a call to GeneratedPluginRegistrant asking it to register itself. This call should be made from the app launch method (application:didFinishLaunchingWithOptions:).
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
Before raising this issue, try adding another well established plugin (the simplest being path_provider or shared_preferences) to see if you get the error here as well.
There has been some experiments about using sqflite from a background isolate and I'm not sure about the plugin support here. Anyway the transaction mechanism is not safe across isolate in the same process so I advise using sqflite from the main isolate (it already uses its own thread).
If your case is the same as mine, I have a custom plugin with Kotlin, so I didn't import GeneratedPluginRegistrant.registerWith(this) at the MainActivity. Instead, I implemented it at the start of the configureFlutterEngine() function and it worked perfectly.
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity : FlutterActivity() {
private val CHANNEL = "getEpubs"
var _eventSink: EventChannel.EventSink? = null
override fun configureFlutterEngine(#NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
}
This registers the generated sqflite plugin access to the database on the device.
(Sorry for the Kotlin code, but you can change it to Java.)
Don't forget to import:
io.flutter.plugins.GeneratedPluginRegistrant
This may be because one of the other plugins in your project is failing during plugin registration and preventing other plugins listed below it from being registered.
If you see the line below in your logs,
Tried to automatically register plugins with FlutterEngine #{engine hash appears here} but could not find and invoke the GeneratedPluginRegistrant;
set a break point in GeneratedPluginRegister's registerGeneratedPlugins() static method to see what exception is being thrown.
In my case I was using a plugin that called io.flutter.plugin.common.PluginRegistry.Registrar's activity() method which returns null when there is no foreground activity in the application.

Crashlytics with Ionic 3 app

I have implemented Firebase plugin with ionic 3 app. It is working fine. Could you tell me how can I use Crashlytics with this plugin? According to the doc it seems for the native apps. So how can we do it with Ionic 3?
There is a plugin cordova-fabric-plugin which we can use with ionic apps. But it seems we don't need it anymore since this note on the native apps doc: Any guidance please?
Note: If you're upgrading from Fabric Crashlytics, remove the Fabric
API key from your AndroidManifest.xml. Delete the key's meta-data tag,
which should have io.fabric.ApiKey and the API key.
In theory you should setup the FabricPlugin just as described. (the versions required of the firebase are lower than the once included)
To setup on ionic I recommend to read the following issue: https://github.com/sarriaroman/FabricPlugin/issues/70
Short Version: Create then a custom error handler
{provide: ErrorHandler, useClass: FabricErrorHandler},
and then your custom Error Handler
import {Injectable} from "#angular/core";
import {IonicErrorHandler } from 'ionic-angular';
import * as stacktrace from 'stacktrace-js';
#Injectable()
export class FabricErrorHandler extends IonicErrorHandler {
constructor (public analytics: Analytics) {
super();
}
handleError(error) {
window.fabric.Crashlytics.addLog('crash triggered');
stacktrace.get().then(
trace => window.fabric.Crashlytics.endNonFatalCrash(error.message, trace)
);
super.handleError(error);
}
}
Refer this link
https://fabric.io/kits/android/crashlytics/features
Crashlytics with Ionic 3 app
First off, follow what they say… installing the IDE plugin, etc.
Now. Ionic uses gradle for its building. You would expect the install to work right away, but it wont. Ionic/Cordova overwrites the build.gradle definitions in the dependencies section.
Anyway, first off open build.gradle, and in buildscript > repositories, if its not already in there, add
jcenter() maven { url 'https://maven.fabric.io/public' }
Next, there are 3 dependencies for each gradle version. if you know what version you are running, great. otherwise add the following to all of them.
classpath 'io.fabric.tools:gradle:1.+'
Now what we need to do is extend gradle’s build.
Create a file in your android/ios directory called build-extras.gradle.
Inside this, we need to define the repositories.
apply plugin: 'io.fabric' repositories { jcenter() maven { url 'https://maven.fabric.io/public' } } dependencies { // Crashlytics Kit compile('com.crashlytics.sdk.android:crashlytics:2.5.5#aar') { transitive = true } }
Now, when you run or build the app, it should work, although Fabric.io 79 won’t recognize your app.
We will need to install a cordova plugin,
The one I use is:
https://www.npmjs.com/package/cordova-fabric-plugin 946
After this is installed, add a force crash and rebuild & run your app.
If it is still not working, make sure you do not have any ad-blocking software installed. Even if you don’t but you have in the past, reinstall it and make sure all settings are reset (I.E AdAway edits your hosts files, uninstalling it does not reset them, you need to reset them then you can uninstall them).
Hope this has helped anyone else who had issues setting it up.
EDIT
Currently Crashlytics does not support custom stacktraces. All crashes will come from the Crashlytics/Fabric.io plugin. You have to use the logs to specify the error.
Fabric does not support any non-native platforms except for Unity at this time. However, as #wodka mentioned, there are community workarounds.

Unity ios build work with debug mode but crash with release mode (archive ipa)

I'm trying to use sqlite with sqlcipher for unity ios game.
I get an sqlite unity example https://github.com/takezoux2/unity-orm
I added a method for unity to call function set key:
[DllImport("__Internal", EntryPoint = "sqlite3_key")]
private static extern int sqlite3_key(IntPtr stmHandle, string key, int len);
I compiled sqlcipher to static library (libsqlcipher.a). Add it to Assets/Plugins/iOS with header sqlite3.h, sqlite3ext.h
In Unity editor, it works without encryption. It's ok. I just want encryption work on ios devices.
I keep moving on export Xcode project, config OPENSSL_SRC in Source trees, add C flag -DSQLITE_HAS_CODEC, add search header "sqlcipher", add Security framework then run on device.
It works! There is no issue. I get the database encrypted in Document folder (i tested it with hexdump -C, SQLiteManager)
The problem only occurred after I archive the app to ipa file (using enterprise provisioning profile). I Use iFunbox to install app to device. The app crash immediately on launch.
This is what i get from crash log:
Exception Type: EXC_BAD_ACCESS (SIGABRT)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000000
I try to replace sqlite3_key with PRAGMA key='123456';
No more crash, everything works but the output database is not encrypted.
I don't know what different between Archive and Build mode. My example works if i build directly to device (with both sqlite3_key and PRAGMA key='123456';), but archive mode does not.
I also try to import sqlcipher xcode project to unity xcode project (remove libsqlcipher.a from Plugins/iOS), set all architectures to armv7 (also try with/without -mno-thumb), add C flag -DSQLITE_HAS_CODEC, add search header "sqlcipher", add Security framework then run directly on device. It work!!!
Then i try to archive app, install app with iFunbox. Again, i get crash on launch.
I'm not sure if i'm setting something wrong with my project (https://github.com/tamhv/unity-orm-with-encrypt). Please someone take a look on this and give me advice. Thank you so much!
I can't tell you why you are crashing, but you can switch your app to Release mode and then debug it to find out.
In XCode, On the top toolbar next to the play/stop button press on the Project name to bring up the context menu and select Edit Schema.
Under Run/Debug change the Build configuration to Release.
Now run the app from XCode and hopefully you'll see the same crash but have a stack trace.

Resources