Как отключить отчеты о сбоях Firebase, когда приложение работает на отладке?

Я успешно реализовал Firebase Crash Reporting, но мне нужно отключить службу, когда приложение работает отменить вариант сборки "debug", чтобы избежать нереальных сбоев в консоли во время разработки.

в официальной документации об этом ничего не говорится.

14 ответов


обновление: С Google Play Services / Firebase 11+ Теперь вы можете отключить отчеты о сбоях во время выполнения. FirebaseCrash.setCrashCollectionEnabled() (спасибо @Tyler Carberry)

ОТВЕТ:

официальной поддержки для этого нет, насколько сообщество смогло предположить. Лучший способ сделать это-настроить несколько приложений Firebase на панели мониторинга, по одному для каждого типа сборки, и настроить несколько google_services.файлы json, направляющие в каждое приложение в зависимости от варианта сборки.


С Google Play Services 11.0 теперь вы можете отключить отчеты о сбоях во время выполнения.

FirebaseCrash.setCrashCollectionEnabled(!BuildConfig.DEBUG);

недавно была введена возможность отключить Firebase аварии отчетности в официальном порядке. Вам необходимо обновить Firebase Android sdk по крайней мере до версии 11.0.0

для этого вам нужно отредактировать свой AndroidManifest.xml и добавить:

<meta-data
   android:name="firebase_crash_collection_enabled"
   android:value="false" />

внутри <application> блок.

вы можете проверить, включен ли отчет о сбое Firebase во время выполнения с помощью FirebaseCrash.isCrashCollectionEnabled ().

ниже a полный пример отключения отчетов о сбоях Firebase в отладочных сборках.

построить.Gradle в:

...
 buildTypes {

    release {
        ...
        resValue("bool", "FIREBASE_CRASH_ENABLED", "true")
    }

    debug {
        ...
        resValue("bool", "FIREBASE_CRASH_ENABLED", "false")

    }

}
...
dependencies {
    ...
    compile "com.google.firebase:firebase-core:11.0.0"
    compile "com.google.firebase:firebase-crash:11.0.0"
    ...
}

AndroidManifest.в XML:

 <application>

    <meta-data
        android:name="firebase_crash_collection_enabled"
        android:value="@bool/FIREBASE_CRASH_ENABLED"/>
...

в моем классе приложений onCreate ()

if (BuildConfig.DEBUG) {
    Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
            Log.wtf("Alert", paramThrowable.getMessage(), paramThrowable);
            System.exit(2); //Prevents the service/app from freezing
        }
    });
}

он работает, потому что он принимает oldHandler, который включает Firebase one

 final UncaughtExceptionHandler oldHandler = Thread.getDefaultUncaughtExceptionHandler();

из пути переработки


вы можете изменить зависимость сбоя firebase на зависимость только для выпуска.

для этого вы определяете его как зависимость releaseCompile

releaseCompile 'com.google.firebase:firebase-crash:9.4.0'

теперь он будет включен только в сборки выпуска. Если у вас есть другие типы пользовательских построений, для которых вы хотите отчеты о сбоях, вы можете добавить их к ним.

customBuildTypeCompile 'com.google.firebase:firebase-crash:9.4.0'

простой и легкий трюк, который я использовал, - добавить зависимость от отчетов о сбоях firebase в сборке выпуска только в .

это удалит библиотеку отчетов о сбоях из типа сборки отладки и добавит это только в сборку выпуска.

dependencies {
    releaseCompile 'com.google.firebase:firebase-crash:10.2.0'
}

вдохновленный это связано ответа и другие здесь, я придумал это удобное решение.

используя Лесной для ведения журнала я создал различные реализации подкласса дерева для сборки отладки и выпуска. В debug он переносится на DebugTree, который записывает в logcat. В выпуске он пересылает исключения и журналы с высоким приоритетом в Firebase, отбрасывая остальное.

построить.Gradle в

dependencies {
  ...
  compile 'com.jakewharton.timber:timber:4.3.0'
  releaseCompile 'com.google.firebase:firebase-crash:9.0.2'
}

src / debug / java/[пакет] / лесной пожар.java

import timber.log.Timber;

public class ForestFire extends Timber.DebugTree {}

src / release / java/[пакет] / лесной пожар.java

import android.util.Log;
import com.google.firebase.crash.FirebaseCrash;
import timber.log.Timber;

public class ForestFire extends Timber.Tree {
  @Override
  protected void log(int priority, String tag, String message, Throwable t) {
    if (Log.WARN <= priority) {
      FirebaseCrash.log(message);
      if (t != null) {
        FirebaseCrash.report(t);
      }
    }
  }
}

запуске приложения

Timber.plant(new ForestFire());

сначала инициализируйте переменные в файле gradle и проверьте, находится ли он в режиме отладки или выпуска. Лучший способ отправить отчет о сбое находится в пределах класса Application.

построить.Gradle в

    buildTypes {
         release {
             buildConfigField "Boolean", "REPORT_CRASH", '"true"'
             debuggable false
         }
         debug {
             buildConfigField "Boolean", "REPORT_CRASH", '"false"'
             debuggable true
         }
    }

теперь сначала проверьте режим и отправьте отчет о сбоях, если произошел сбой .

приложение.java

    /** Report FirebaseCrash Exception if application crashed*/
    Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
    {
        @Override
        public void uncaughtException (Thread thread, Throwable e)
        {
            /** Check whether it is development or release mode*/
            if(BuildConfig.REPORT_CRASH)
            {
                FirebaseCrash.report( e);
            }
        }
    });

В настоящее время вы не можете отключить отчеты о сбоях firebase, хотя вы можете отключить Firebase analytics.

таким образом, один из способов сделать это-создать другое приложение с другим идентификатором в том же проекте firebase. После этого вам просто нужно изменить appID, чтобы включить или отключить отчеты о сбоях firebase. Я создал два приложения для моего удобства:

AppID: com.android - для типа сборки выпуска

AppID: com.андроид.debug - для отладка типа сборки

пожалуйста следовать ниже ссылкой для больше деталей:

https://firebase.googleblog.com/2016/08/organizing-your-firebase-enabled-android-app-builds.html

Edit: Вам не нужно менять appID в проекте android снова и снова. Существует лучший способ использовать другой appID для отладки типа сборки -

android {
    defaultConfig {
        applicationId "com.android"
        ...
    }
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }
    }
}

проверить ссылку для более подробности:

https://developer.android.com/studio/build/application-id.html

Edit2:

в основном в вышеуказанном решении вы делаете два разных приложения в проекте Firebase, и таким образом вы можете отделить свои ошибки разработки и производства.

FYI Firebase crash reporting устарел. Вы должны использовать Ткани Crashlytics (принадлежит Google). Он имеет некоторые действительно интересные функции.


на FirebaseAnalytics класса.
Отключить сбор:setAnalyticsCollectionEnabled(false);
Включить сбор:setAnalyticsCollectionEnabled(true); или написать AndroidManifest.xml в теге приложения: <meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />

возможно использование:

if (BuildConfig.DEBUG){ //disable for debug
    mFirebaseAnalytics.setAnalyticsCollectionEnabled(false);
}

источник


сначала вам придется создать debug и release построить варианты, а затем установить переменную с логическим значением. Затем вам нужно будет получить это значение из вашего java-файла, который расширяет application Я.е от того, где вы включите Fabric сообщения об ошибках.

ниже приведен пример кода.

в вашем приложении добавьте следующие строки, чтобы создать 2 варианта сборки debug и release а затем добавьте переменную с boolean значение.

defaultConfig {
    buildConfigField 'boolean', 'ENABLE_ANALYTICS', 'true'
}

buildTypes {
    debug {
        applicationIdSuffix ".debug"
        versionNameSuffix 'DEBUG'
        buildConfigField 'boolean', 'ENABLE_ANALYTICS', 'false'
    }
    release {
        minifyEnabled false
    }
}

тогда, когда вы пытаетесь добавить Fabric crash reporting проверьте значение для ENABLE_ANALYTICS

public class Test расширяет приложение {

private GoogleAnalytics googleAnalytics;
private static Tracker tracker;

@Override
public void onCreate() {
    super.onCreate();
    if (BuildConfig.ENABLE_ANALYTICS)
        Fabric.with(this, new Crashlytics());
    }
}

вы можете увидеть значение для ENABLE_ANALYTICS by ctrl + щелчок на значении. Надеюсь, это поможет.


я использую versionCode как фильтр для локальных / производственных сборок.

gradle.свойства

VERSION_CODE=1

app / build.Gradle в

android {
    defaultConfig {
        versionCode VERSION_CODE as int
    }
}

при публикации новой версии приложения, просто установите новое значение из командной строки:

./gradlew build -PVERSION_CODE=new_value

в противном случае, когда вы строите из Android Studio, вы всегда получите то же самое versionCode, поэтому вы можете легко различать отчеты о сбоях в консоли Firebase.


как было сказано ранее-нет официального способа сделать это. Но худшее обходное решение для меня, как упоминалось @mark-d, - сбросить DefaultUncaughtExceptionHandler (https://stackoverflow.com/a/39322734/4245651).

но если вы просто позвоните System.exit(2) как было предложено-приложение будет мгновенно закрыто на исключение, без каких-либо диалоговых сообщений и труднодоступных журналов отладки. Если это важно для вас, есть способ восстановить по умолчанию обработчик:

if (BuildConfig.DEBUG) {
        final Thread.UncaughtExceptionHandler currentHandler = Thread.getDefaultUncaughtExceptionHandler();
        if (currentHandler.getClass().getPackage().getName()
                                                .startsWith("com.google.firebase")) {
            final Thread.UncaughtExceptionHandler defaultHandler = 
                getPrivateFieldByType(currentHandler, Thread.UncaughtExceptionHandler.class);
            Thread.setDefaultUncaughtExceptionHandler(defaultHandler);
        }
}

здесь

public static <T> T getPrivateFieldByType(Object obj, Class<T> fieldType) {
    if (obj != null && fieldType != null) {
        for (Field field : obj.getClass().getDeclaredFields()) {
            if (field.getType().isAssignableFrom(fieldType)) {
                boolean accessible = field.isAccessible();
                if (!accessible) field.setAccessible(true);
                T value = null;
                try {
                    //noinspection unchecked
                    value = (T) field.get(obj);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if (!accessible) field.setAccessible(false);
                return value;
            }
        }
    }
    return null;
}

public class MyApp extends Application {
    public static boolean isDebuggable;

    public void onCreate() {
        super.onCreate();
        isDebuggable = (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));
        FirebaseCrash.setCrashCollectionEnabled(!isDebuggable);
    }
}