Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Boost the Quality of Your App with Firebase (May 22, 2018 Londroid)

Boost the Quality of Your App with Firebase (May 22, 2018 Londroid)

Doug Stevenson

May 24, 2018
Tweet

More Decks by Doug Stevenson

Other Decks in Technology

Transcript

  1. Boost the Quality of Your App
    with Firebase
    Doug Stevenson
    @CodingDoug

    View full-size slide

  2. 50%
    Stability & bugs
    When leaving a 1 star review, 50% of the time the user mentions
    the app stability and bugs
    Google analysis on Play reviews, top 10 English speaking countries, last 365 days of reviews
    @CodingDoug

    View full-size slide

  3. Prevention
    Find the bugs before your users!

    View full-size slide

  4. Firebase Test
    Lab
    Test Artifacts
    • Logcat (crashes)
    • Videos
    • Screenshots
    • Performance

    CPU

    memory

    network ingress/egress
    @CodingDoug

    View full-size slide

  5. Instrumented Tests
    • Specific to Android
    • Focus on the user story / use case
    • Espresso / UI Automator
    • Adds extensions to JUnit
    • Android Testing Support Library: goo.gl/xSxzoj
    • Testing Codelab: goo.gl/RHdFBY
    @CodingDoug

    View full-size slide

  6. @RunWith(AndroidJUnit4.class)
    public class NotesScreenTest {
    @Rule
    public ActivityTestRule mNotesActivityTestRule =
    new ActivityTestRule<>(NotesActivity.class);
    @Test
    public void clickAddNoteButton_opensAddNoteUi() throws Exception {
    // Click on the add note button
    onView(withId(R.id.fab_add_notes)).perform(click());
    // Check if the add note screen is displayed
    onView(withId(R.id.add_note_title)).check(matches(isDisplayed()));
    }
    }
    @CodingDoug

    View full-size slide

  7. (Local) Unit Tests
    • Runs fast on your computer
    • Focus on testing individual classes and methods
    • Dependency injection / object mocking
    @CodingDoug

    View full-size slide

  8. Android Instrumented Tests
    Local Unit Tests
    @CodingDoug

    View full-size slide

  9. Protip: Run your unit tests along with instrumented tests
    android {

    sourceSets {

    androidTest {

    java.srcDirs += "src/test/java"

    }

    }

    }
    testImplementation 'org.mockito:mockito-core:2.17.0'

    androidTestImplememntation 'org.mockito:mockito-android:2.17.0'
    @CodingDoug

    View full-size slide

  10. Protip: Enable StrictMode when running in Test Lab
    Turn StrictMode violations into actionable crash reports in Test Lab.
    @CodingDoug

    View full-size slide

  11. // During Application.onCreate() or ContentProvider.onCreate()
    private void enableStrictMode() {
    if (shouldEnableStrictMode()) {
    StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
    .detectAll()
    .penaltyLog()
    .penaltyDeath()
    .build());
    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
    .detectAll()
    .penaltyLog()
    .penaltyDeath()
    .build());
    }
    }
    @CodingDoug

    View full-size slide

  12. private boolean shouldEnableStrictMode() {
    return BuildConfig.DEBUG;
    }
    @CodingDoug

    View full-size slide

  13. private boolean shouldEnableStrictMode() {
    ContentResolver resolver = context.getContentResolver();
    String isRunningInTestLab =
    Settings.System.getString(resolver, "firebase.test.lab");
    return BuildConfig.DEBUG || "true".equals(isRunningInTestLab);
    }
    @CodingDoug

    View full-size slide

  14. // https://issuetracker.google.com/issues/36951662
    private void workaroundEnableStrictMode() {
    enableStrictMode();
    if (Build.VERSION.SDK_INT >= 16) {
    // restore strict mode after onCreate() returns.
    new Handler().postAtFrontOfQueue(new Runnable() {
    @Override
    public void run() {
    enableStrictMode();
    }
    });
    }
    }
    @CodingDoug

    View full-size slide

  15. But I don’t want to write tests
    @CodingDoug

    View full-size slide

  16. Espresso Test Recorder
    • Android Studio

    Menu → Run → ⚫︎Record Espresso Test
    • Interact with your app
    • Generates Espresso code to match your actions
    @CodingDoug

    View full-size slide

  17. But I don’t even want to have tests
    @CodingDoug

    View full-size slide

  18. Robo Test
    • Only an APK with is required
    • Automatically logs in with Google Auth
    • Can pre-fill form fields (e.g. user/pass login, search)
    • Configure maximum crawl depth and timeout
    • Algorithm improves over time
    • Additional test artifact: Activity map
    • Roboscript
    @CodingDoug

    View full-size slide

  19. But I’m building a game
    @CodingDoug

    View full-size slide

  20. Game Loop Test (beta)
    • Sequence of scenarios driven by Android Intents
    • Performance += FPS
    • Game Loop Codelab: goo.gl/sn4RNp
    • “Mechahamster” sample game
    • Project home: goo.gl/8chQ8p
    • Test Lab Guide: goo.gl/16xSPn
    @CodingDoug

    View full-size slide

  21. How do I run a test?
    @CodingDoug

    View full-size slide

  22. gcloud firebase test android run \
    --type instrumentation \
    --app app-debug-unaligned.apk \
    --test app-debug-test-unaligned.apk \
    --device model=Nexus6,version=21,orientation=portrait \
    --device model=Nexus7,version=19,orientation=landscape
    @CodingDoug

    View full-size slide

  23. Community Support for testing with CI
    • Walmart’s “Flank” for sharding tests

    goo.gl/5ApxVU
    • Circle CI integration

    goo.gl/xoPFqY
    @CodingDoug

    View full-size slide

  24. Billing for Firebase Test Lab
    • Spark and Flame payment plans: daily limits
    • Virtual devices: 10 tests/day
    • Physical devices: 5 tests/day
    • Blaze payment plan: per-minute billing
    • Virtual devices: $1/device/hour
    • Physical devices: $5/device/hour
    @CodingDoug

    View full-size slide

  25. Crashlytics features
    • Unity support
    • NDK support
    • Search
    • Webhooks
    • Cloud Functions trigger
    • Integration with Google Analytics for Firebase
    • Integration with Slack (new!)
    @CodingDoug

    View full-size slide

  26. public interface UncaughtExceptionHandler {
    /**
    * Method invoked when the given thread terminates due to the
    * given uncaught exception.
    * Any exception thrown by this method will be ignored by the
    * Java Virtual Machine.
    * @param t the thread
    * @param e the exception
    */
    void uncaughtException(Thread t, Throwable e);
    }
    @CodingDoug

    View full-size slide

  27. public class MyHandler implements Thread.UncaughtExceptionHandler {
    private final Thread.UncaughtExceptionHandler mPriorExceptionHandler;
    public MyHandler(Thread.UncaughtExceptionHandler prior) {
    mPriorExceptionHandler = prior;
    }
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
    // Deal with throwable here
    if (mPriorExceptionHandler != null) {
    mPriorExceptionHandler.uncaughtException(thread, throwable);
    }
    }
    }
    @CodingDoug

    View full-size slide

  28. Thread.UncaughtExceptionHandler prior =
    Thread.getDefaultUncaughtExceptionHandler();
    Thread.setDefaultUncaughtExceptionHandler(
    new MyUncaughtExceptionHandler(prior));
    @CodingDoug

    View full-size slide

  29. Performance == Quality
    @CodingDoug

    View full-size slide

  30. 60%
    Speed, design & usability
    When leaving a 5 star review, 60% of the time the user mentions
    the speed, design or usability
    Google analysis on Play reviews, top 10 English speaking countries, last 365 days of reviews
    @CodingDoug

    View full-size slide

  31. https://goo.gl/BnWcPK

    View full-size slide

  32. Systrace
    Advantages
    • Lots of detail
    • Custom traces
    Disadvantages
    • App runs slow
    • You typically have to know what you're looking for
    • Can't collect data from the wild, only connected devices
    @CodingDoug

    View full-size slide

  33. Firebase Performance Monitoring
    • Runs in production
    • Negligible overhead
    • Automatic and Custom traces
    • Automatic HTTP/S traffic metrics
    @CodingDoug

    View full-size slide

  34. Trace
    • A report for a period of time with a well-defined beginning and end
    • Nominally has a duration
    • Also may contain “metrics" for performance-related events during the trace
    @CodingDoug

    View full-size slide

  35. Automatic Traces - no coding necessary!
    • App Start (cold)
    • Screen (each Activity start / stop)
    • App in foreground
    • App in background
    @CodingDoug

    View full-size slide

  36. Automatic Traces - App Start
    ContentProvider.onCreate() Activity.onResume()
    But you might want something different!
    @CodingDoug

    View full-size slide

  37. Manual Traces
    • Trace trace = FirebasePerformance.startTrace(name);
    • trace.stop();
    • @AddTrace annotation
    @CodingDoug

    View full-size slide

  38. Metrics
    • Associate a string/int pair to a Trace
    • Typically better to measure ratios than absolute values
    • Abs value if you want to compare similar metrics between traces
    cache_hit++
    cache_miss++
    dropped_frames += 10
    @CodingDoug

    View full-size slide

  39. Opinionated Performance Dashboard
    @CodingDoug

    View full-size slide

  40. Android Vitals - get clues for what to measure
    • In the Google Play Console: goo.gl/rkztG1
    • Performance-related stats
    • Slow rendering (jank)
    • Frozen frames
    • Stuck WakeLocks
    @CodingDoug

    View full-size slide

  41. Automatic HTTP/S transaction metrics
    • Response time
    • Payload size
    • Success rate
    • URL pattern globbing


    yourcdn.com/*.jpg

    api.yourdomain.com/v1/users/*

    api.yourdomain.com/v1/users/*/history/*
    @CodingDoug

    View full-size slide

  42. HTTP/S transaction metrics breakdown
    • App version
    • Device
    • Country
    • OS level
    • Carrier
    • Radio
    @CodingDoug

    View full-size slide

  43. Network Performance Summary
    @CodingDoug

    View full-size slide

  44. How HTTP/S monitoring works
    Build time bytecode manipulation (with ASM)
    URL url = new URL("https://firebase.google.com");

    HttpsURLConnection conn = (HttpsURLConnection)

    url.openConnection();
    URL url = new URL(“https://firebase.google.com”);

    HttpsURLConnection conn = (HttpsURLConnection)

    FirebasePerfUrlConnection.instrument(url.openConnection());
    Decorator inside!
    @CodingDoug

    View full-size slide

  45. How HTTP/S monitoring works
    buildscript {

    dependencies { classpath ‘com.google.firebase:firebase-plugins:1.1.5' }

    }
    apply plugin: 'com.google.firebase.firebase-perf'
    dependencies {

    compile ‘com.google.firebase:firebase-perf:15.2.0'

    }
    Uses the Transform API: goo.gl/PwBcLE
    @CodingDoug

    View full-size slide

  46. Firebase Remote Config
    • Use it to plan and stage rollouts of new features
    • Quickly back off the new feature if it has problems
    @CodingDoug

    View full-size slide

  47. FirebaseRemoteConfig rc = FirebaseRemoteConfig.getInstance();
    if (rc.getBoolean("using_cool_new_feature")) {
    // do cool new stuff
    }
    else {
    // do the boring old stuff
    }
    @CodingDoug

    View full-size slide

  48. Firebase Remote Config
    • Find out what your users prefer by experimentation
    • Study the results in Google Analytics for Firebase
    @CodingDoug

    View full-size slide

  49. Firebase Remote Config (for perf)
    • Compare CDN/server performance
    • Compare cache configuration strategies
    @CodingDoug

    View full-size slide

  50. final FirebaseRemoteConfig rc = FirebaseRemoteConfig.getInstance();
    int cache_size = (int) rc.getLong("cache_size");
    // init cache with cache_size
    // later...
    Trace trace = FirebasePerformance.startTrace("my_trace");
    Item item = cache.get("some_resource");
    if (item != null) {
    trace.incrementMetric("cache_hit_size_" + cache_size);
    }
    else {
    trace.incrementMetric(“cache_miss_size_" + cache_size);
    }
    trace.stop();
    @CodingDoug

    View full-size slide

  51. Resources
    • Firebase home

    https://firebase.google.com/
    • Slack

    https://firebase.community/
    • YouTube

    http://youtube.com/firebase
    • Blog

    http://firebase.googleblog.com/
    • Twitter

    https://twitter.com/Firebase

    View full-size slide

  52. Thank you!
    Confidential + Proprietary
    Doug Stevenson
    @CodingDoug
    youtube.com/firebase
    firebase.googleblog.com

    View full-size slide