I am struggling to implement Google's Firebase push notifications in a mature MVVMcross application. We are being forced to seek a new solution to our current one because it appears that the functionality is about to be deprecated in AppCenter.
We've placed the code inside the RootActivity file (at the bottom of the method)
protected override void OnCreate(Bundle bundle)
When I run the app in a USB/debug scenario on my Android Galaxy I get the current error "Default FirebaseApp is not initialized in this process"
I tried to use the approach that was recommended in the error message to no avail:
FirebaseApp.InitializeApp(RootActivity.Context);
FirebaseMessaging.Instance.GetToken().AddOnCompleteListener(new OnCompleteListener());
In case anyone is wondering here is the code for the method that is mentioned above was setup for testing purposes using a breakpoint:
public class OnCompleteListener : Java.Lang.Object, IOnCompleteListener
{
public void OnComplete(Android.Gms.Tasks.Task task)
{
var token = task.Result.ToString();
}
}
We initially tested this in a standard Xamarin Forms Android app for testing and didn't have any problem with getting the token but we hit the wall when we played with it in our client's MVVMcross app.
I would also like to mention that I have tried the following solution with no luck as well:
var setupSingleton = MvxAndroidSetupSingleton.EnsureSingletonAvailable(Context);
setupSingleton.EnsureInitialized();
FirebaseMessaging.Instance.GetToken().AddOnCompleteListener(new OnCompleteListener());
I found that I had two problems. The first one was the fact that my project name did not match in my manifest and google services key. I was using my own key that I setup for testing. After I realized this I switched back to my client's key and double checked that it was part of the build. As soon as I resolved that issue I found that I needed to install the nuget package for Xamarin.Google.Dagger to resolve the reflection issues. After taking care of that I did a clean/rebuild and ran the debug on my Galaxy S20 test device. This fix allowed me to hit my test break point that I setup for testing the token reception from FCM.
Related
I am trying to set up the Flutter sign_in_with_apple package but run into problems with the android side.
What I have done so far, following the package README to the letter:
Set up the glitch.me server. The server is up and listening at https://MYSERVER.glitch.me/callbacks/sign_in_with_apple I've added a bit of console logging to make sure I know when the server is hit.
Set up appid and serviceid on the apple developer console. Service identifier is com.company.foobar.dev.signin
Added the glitch callback https://MYSERVER.glitch.me/callbacks/sign_in_with_apple as the return url on the service configuration.
Copied the activity block from the readme into my android manifest. NOTE: I didn't know what to set the name. Leave it referring to the package or change it to my app id? It's currently android:name="com.aboutyou.dart_packages.sign_in_with_apple.SignInWithAppleCallback"
Add this block to my flutter service:
"https://MYSERVER.glitch.me/callbacks/sign_in_with_apple";
final appleIdCredential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
webAuthenticationOptions: WebAuthenticationOptions(
clientId: "com.company.foobar.dev.signin",
redirectUri: Uri.parse(redirectURL)));
Unfortunately, the call to SignInWithApple.getAppleIDCredential in step 5 throws an exception and I am seeing invalid_request invalid web redirect url. The glitch server is never even hit, which makes me think that even if I messed up at Step 4 (the intent name in the android manifest) the problem is more likely in the apple developer console setup. However, I am pretty sure I've followed the README and I am running out of ideas.
Hmmm, I threw away the apple developer console service setup for the dev package (with applicationIdSuffix '.dev' and bundleid 'com.company.foobar.dev') and set up the same for the production flavor. This one works as expected.
I am now wondering if apple doesn't even redirect the request to the glitch server for android unless the package has as playstore presence. Comments?
I'm working with AppsFlyer in Unity based on the following documentation: https://support.appsflyer.com/hc/en-us/articles/213766183-Unity-plugin-V4-integration-guide-for-developers
I followed the necessary steps but when it came to running the integration test, it just stayed stuck in this screen:
https://imgur.com/a/taXW909
Are there any potential things that I might be missing that could cause this issue? As far as I understand, I need to whitelist my Android device, select it in the SDK Integration Test, scan the QR Code, install my project's .apk file and the AppsFlyer should start detecting something.
Additional details
Here's the script for initializing AppsFlyer:
public class AppsFlyerObject : MonoBehaviour
{
private const string AppsFlyerKey = /* MY DEV KEY */;
private void Start()
{
AppsFlyer.setAppsFlyerKey(AppsFlyerKey);
AppsFlyer.init(AppsFlyerKey, "AppsFlyerTrackerCallbacks");
}
}
Regarding the AppsFlyer app, here're the settings I selected:
https://imgur.com/a/7PxEnlW
I want to test an APK file that is not present on any kind of a store.
Have you tried testing a non-organic install with this link?
https://support.appsflyer.com/hc/en-us/articles/207032126#integration-43-simulating-a-nonorganic-install
If everything implemented correctly, but you are still stuck on this screen - it's very likely you have 'zero plan' on your AppsFlyer account. You cannot pass this test on free plan for some reason.
I've found it after two days by connecting device via logcat and recieving 403 error. You can do same to be sure its your reason too.
I am very much new to AirWatch Concept but had gone thoroughly about AirWatch. I have gone through the following links,
http://developer.air-watch.com/android/application-configuration-with-the-android-sdk/
http://developer.air-watch.com/android/android-sdk-setup/
but in vain.
Could anyone please help me regarding the integration of Air Watch in Android ?
Things i have done so far,
I have created app in the https://apidev.awmdm.com, and i have added assignemnts. The question here is, How can i get the assignment details in my android application that were added in the Air Watch Console.
Help is really appreciated.
Update:
I am able to create and push the application from AIR WATCH CONSOLE to my Device. Now, the issue i am facing is, If i am adding some application configuration in the AIR WATCH CONSOLE, i am not able to get those details in my application.
I have gone through the below Url for the above scenario,
https://appconfig.org/android/ which is very much similar to https://appconfig.org/ios/
I have implemented those things that were mentioned in the above url but still then i am not able to get those details.Please let me know if i am wrong anywhere.
I got to know that the key value pairs that were being passed in Air watch console will be coming into com.apple.configuration.managed key in iOS. Does any one have an idea that how these key value pairs will come. As far as i know, they will be handled via Restriction Manager. But no idea/clue how to handle in Android.
Updated:
xml/app_restrictions.xml:
<?xml version="1.0" encoding="utf-8"?>
<restrictions xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<restriction
android:key="ManagedServer"
android:restrictionType="string"
android:title="Managed Server"
tools:ignore="ValidRestrictions" />
<restriction
android:key="#string/mdm_key_managed_server_name"
android:restrictionType="string"
android:title="#string/mdm_key_managed_server_url"
tools:ignore="ValidRestrictions" />
<restriction
android:key="#string/mdm_key_managed_server_url"
android:restrictionType="string"
android:title="#string/mdm_key_managed_server_url"
tools:ignore="ValidRestrictions" />
</restrictions>
oncreate Method :
IntentFilter restrictionsFilter =
new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get the current configuration bundle
Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
// Check current configuration settings, change your app's UI and
// functionality as necessary.
Toast.makeText(LoginActivity.this, "Reciever Called", Toast.LENGTH_LONG).show();
RestrictionsManager myRestrictionsMgr =
(RestrictionsManager)
getSystemService(Context.RESTRICTIONS_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
if (myRestrictionsMgr != null) {
Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
if (appRestrictions != null) {
if (appRestrictions.containsKey("ManagedServer")) {
String mConfigDetails = appRestrictions.getString("Managed Server");
Toast.makeText(LoginActivity.this, "" + mConfigDetails, Toast.LENGTH_LONG).show();
}
}
}
}
}
};
registerReceiver(restrictionsReceiver, restrictionsFilter);
List of Users:
When i am actually trying the other command:
Update:
Created a sample app and published to Play Store. App link as follows,
https://play.google.com/store/apps/details?id=com.manu.samplemdm
Now, its a play store app. When I am sending Application Configuration but unable to receive it in the Application. Its giving me still empty bundle from the application.
Help would be really appreciated.
Help is really appreciated
Beside AirWatch Resources, which tells you how you can create an app and set the app configurations,key-value pairs, to push to your devices, You need to check out Android Restriction Manager API. Follow the steps described in the link.
How the whole process works is, AirWatch controls AndroidForWork environment after you set your MDM as AirWatch. And then, AirWatch manages the device from AirWatch console and it pushes the App Configuration to AndroidForWork in your device. You need to implement Android Restriction Manager to access to these data passed you by your MDM. It goes same for all of the MDMs in the Market.
Update:
In order to install your app into Work Container in the development phase, you can use adb to copy it from Personal Container to Work Container.
First, list all of the active users in the device:
./adb shell pm list users
And later, find the Work User's ID from the List of Users and set it in the command below along with your app's package name and App's Main Activity.
./adb shell am start —user 13 -n “your.apps.package.name/your.main.activity.package.name”
13 up there in the command is the Work User's ID. In my case, it's 13.
For more information about ./adb commands in Managed Profiles, see this link and check the most bottom of the page.
There are a couple of different approaches to integrating with AirWatch. It depends on the technology set you're trying to use. I think these are the 2 that are most relevant to you based on what I see in your post:
AirWatch SDK
AppConfig Standard
Both these approaches can accomplish similar functionality but each have different deployment requirements. It sounds like you have gone with the second approach which is using the AppConfig standard and the native APIs provided by Google to have an app read configuration values delivered through AirWatch.
One important thing to note is the AppConfig standard approach on Android requires the device to support "Android for Work" enrollment which is a relatively newer management protocol released by Google. It's worth noting that AirWatch does support Android for Work enrollment so it may just be a matter of getting your AirWatch test instance configured for "Android for Work enrollment" instead of the traditional older Android enrollment protocol. More information about Android for Work can be found here:
https://enterprise.google.com/android/solutions/personal/
If you're already a customer of AirWatch, it may be helpful to create an account here on their resource portal if you haven't done so already to get access to documentation about how you can setup Android for Work within AirWatch. https://resources.air-watch.com
I hope this helps.
I recently released an application for some users to use my newly made Android Application. However, they are having trouble when they perform the Facebook Login feature that I have made.
It seems to work fine on my phone, but on other phones it seems to crash. I would like to know what is causing the application to crash so I can further debug this. Is there anywhere or anything that I can use to debug this problem further?
I have looked at both the Facebook Developer Console and Google Play Developer Console and neither seem to show or point me to where my error is. If anyone could help that would be great. Thanks!
Use any Crashlytics/Analytics tools to not only get error logs but also usage statictics which can be pretty useful insight during pre-release tests. Some of them like Crashlytics by Fabric are even free and are very easy to integrate. But, there are many others too.
There are plenty of cloud hosted solutions.These might be paid, and require signing up.
If you want to roll you own simple reporting mechanism, then there is an Android library: ARCA . You can set it up to send crash reports to an email address.
First, you'll need to include the library in app's build.gradle file:
compile 'ch.acra:acra:4.9.0'
Then declare extent the Application class (or modify if you already have) as :
import org.acra.*;
import org.acra.annotation.*;
#ReportsCrashes(mailTo = "reports#yourdomain.com",
mode = ReportingInteractionMode.TOAST,
resToastText = R.string.crash_toast_text)
public class MyApplication extends Application {
#Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// The following line triggers the initialization of ACRA
ACRA.init(this);
}
}
The two thing necessary are:
Add #ReportsCrashes annotation to app's application class, with recipient mail address.
Override attachBaseContext() and include ACRA.init() in it.
Official docs:
Setting up ARCA.
Advanced configuration.
I'm using EasyTracker in my Android App and I need a way to disable Analytics tracking when the app is in "development" or "testing" mode (I have a flag in a constants file to discriminate).
What's the best way to do so?
Thanks!
I believe the correct way to do this with Version 4 of Analytics is with the Opt Out method
GoogleAnalytics.getInstance(this).setAppOptOut(true);
You could set that method to be set if you build in debug mode. ie.
GoogleAnalytics.getInstance(this).setAppOptOut(BuildConfig.DEBUG);
I am using something similiar to allow users to opt-out of analytics.
I found this information at he following link: https://developers.google.com/analytics/devguides/collection/android/v4/advanced
Edit: Just saw the date of the original question, but thought I would add this answer anyway as it was something I was looking for.
UPDATE: With release of Google Analytics v3 for Android,
The SDK provides a dryRun flag that when set, prevents any data from
being sent to Google Analytics. The dryRun flag should be set whenever
you are testing or debugging an implementation and do not want test
data to appear in your Google Analytics reports.
To set the dry run flag:
// When dry run is set, hits will not be dispatched, but will still be
logged as though they were dispatched.
GoogeAnalytics.getInstance(this).setDryRun(true);
+++ My old answer +++
Just comment the following line in your analytics.xml file while you are in development mode.
<string name="ga_trackingId">UA-****</string>
Google Analytics wouldn't be able to find any tracking id, so EasyTracker won't be able to do its job.
When you are building the app for release, uncomment the line and you're good to go.
If you are building a standalone app(not a library), this will be the easiest way to do it, let the build system figure out if it is a debug build or not.
if(BuildConfig.DEBUG){
GoogleAnalytics.getInstance(this).setDryRun(true);
}
I see on the web that this method does not work well for library projects as there is bug in the build tools which does not set the BuildConfig.DEBUG flag correctly for libraries. Not sure if this issue is fixed now.
You can use a class with a static boolean value let's say DEBUG like this :
public final class BuildMode {
public final static boolean DEBUG = true;
}
In code, just use :
if (BuildMode.DEBUG) ...
This is a solution working on all android SDK versions!
Newest version from firebase has this method that can be put inside App class:
FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(!BuildConfig.DEBUG);
What I'm doing is disabling periodic dispatching, by setting a negative period, in analytics.xml:
<integer name="ga_dispatchPeriod">-60</integer>
or you can do it programmatically, using your flag:
if (testingMode) {
GAServiceManager.getInstance().setDispatchPeriod(-1);
} else {
GAServiceManager.getInstance().setDispatchPeriod(60);
}
That way hits are not sent unless you do it manually.
That should work if you are using only periodic dispatching (never calling .dispatch() manually). Hits not sent before 4 a.m. of the following day are somehow discarded, I guess, as they are not appearing in the reports anyway.
See in Google Analytics Developer Guide:
Note: Data must be dispatched and received by 4 a.m. of the following day,
in the local timezone of each profile. Any data received later
than that will not appear in reports.
More info: https://developers.google.com/analytics/devguides/collection/android/v2/dispatch
My technique is to change the android:versionName in Android Manifest until release time.
For example, 1.0.0.ALPHA until time to build a release APK, at which point you could change to 1.0.0. This way you can still see all of your crash reports later, but they will grouped in analytics.
This SO ticket talks about using the BuildConfig.DEBUG flag to conditionally configure analytics and Atul Goyal's answer references the dryRun flag in v3. Those two things could be a nice setup if you don't care about seeing crash reports during debug in the future, and assuming that the BuildConfig.DEBUG flag works correctly.
I have a different approach to this issue. Sometimes you still want to test that analytics is working correctly, but want to just filter test data out in production reports. My solution to that is to create a custom session-scoped dimension (i.e. AppBuild), in GA for the property which tracks if you are running a debug or production build of the app. In your code after you create the Tracker, put:
// replace 1 with the correct dimension number if you have other dimensions defined
tracker.set("&cd1", BuildConfig.DEBUG ? "debug" : "production");
Then create or modify your GA view to add a filter on AppBuild, excluding debug. This should filter out all debug data from your GA view. You can also add a new view to show debug data.