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

Playing with Fire(base) (DevFest Florida)

Avatar for Eric Fung Eric Fung
November 05, 2016

Playing with Fire(base) (DevFest Florida)

Firebase is a feature-rich platform that provides Android apps with a powerful foundation for acquiring users and keeping them engaged. For a recent news app I developed, I employed Cloud Messaging, Remote Config, Dynamic Links, and App Indexing. In this talk, I'll describe practical examples of how I used these features, as well as a few places where I nearly got burned. I'll explain how I:

● Implemented custom push notifications using Cloud Messaging
● Defined simple A/B tests with Remote Config
● Acquired users with Dynamic Links in app banners
● Used App Indexing to get our app into search results
● Recorded events and user properties to measure performance in Analytics

Download the PDF for a copy with clickable links.

Video available at https://www.youtube.com/watch?v=EBVSbHiuyig

Avatar for Eric Fung

Eric Fung

November 05, 2016
Tweet

More Decks by Eric Fung

Other Decks in Programming

Transcript

  1. Feature Tour Search results highlight app content, and link to

    app @gnufmuffin • DevFest Florida, 2016-11-05
  2. What is it? Gets app into Google search results, and

    associates it with your website @gnufmuffin • DevFest Florida, 2016-11-05
  3. What does it give you? — Install cards for users

    who don't have app @gnufmuffin • DevFest Florida, 2016-11-05
  4. What does it give you? — Install cards for users

    who don't have app — Deep links launch app from search results @gnufmuffin • DevFest Florida, 2016-11-05
  5. What does it give you? — Install cards for users

    who don't have app — Deep links launch app from search results — Viewed content appears in search autocompletion @gnufmuffin • DevFest Florida, 2016-11-05
  6. App Indexing: How To Implement 1. Identify website URL structure

    http://www.shopify.com/blog/really-informative-article http://www.shopify.ca/blog/topics/ http://www.shopify.in/blog/topics/informative @gnufmuffin • DevFest Florida, 2016-11-05
  7. App Indexing: How To Implement 1. Identify website URL structure

    http://www.shopify.com/blog/<title-slug-of-article> http://www.shopify.ca/blog/topics/ http://www.shopify.in/blog/topics/<subject> ! Watch out for shared prefix in paths! @gnufmuffin • DevFest Florida, 2016-11-05
  8. App Indexing: How To Implement 2. Associate website with app

    On Android 6.0+, create a Digital Asset Link — Upload to /.well-known/assetlinks.json @gnufmuffin • DevFest Florida, 2016-11-05
  9. App Indexing: How To Implement 2. Associate website with app

    Example assetlinks.json [ { "relation": [ "delegate_permission/common.handle_all_urls" ], "target": { "namespace": "android_app", "package_name": "com.shopify.blog", "sha256_cert_fingerprints": [ "00:01:02:03…" ] } } ] @gnufmuffin • DevFest Florida, 2016-11-05
  10. App Indexing: How To Implement 2. Associate website with app

    On Android < 6.0, associate in Search Console — Add Android app as a new property — Link webpages to app by adding markup on page — Get Google to crawl your site @gnufmuffin • DevFest Florida, 2016-11-05
  11. App Indexing: How To Implement 2. Associate website with app

    Example markup for /blog/really-informative-article <link rel="alternate" href="android-app://com.shopify.blog/https/↩ www.shopify.com/blog/really-informative-article" /> @gnufmuffin • DevFest Florida, 2016-11-05
  12. App Indexing: How To Implement 2. Associate website with app

    ! Without linkage, user sees chooser @gnufmuffin • DevFest Florida, 2016-11-05
  13. App Indexing: How To Implement 3. Add intent filters to

    Android manifest <intent-filter> … <data android:scheme="https" ↩ android:host="www.example.com" ↩ android:path="/recipes"> … — For each Activity, define one or more handled inbound URLs @gnufmuffin • DevFest Florida, 2016-11-05
  14. App Indexing: How To Implement 3. Add intent filters to

    Android manifest <intent-filter> … <data android:scheme="http" /> <data android:scheme="https" /> <data android:pathPrefix="/blog" /> <data android:host="www.shopify.com" /> <data android:host="www.shopify.ca" /> <data android:host="www.shopify.in" /> … ! All data elements contribute to filter @gnufmuffin • DevFest Florida, 2016-11-05
  15. App Indexing: How To Implement 3. Add intent filters to

    Android manifest http://www.shopify.com/blog/<title-slug-of-article> http://www.shopify.com/blog/topics/<subject> — What if I want different activities to handle URLs with same prefix? @gnufmuffin • DevFest Florida, 2016-11-05
  16. App Indexing: How To Implement 3. Add intent filters to

    Android manifest @Override protected void onCreate(Bundle savedInstanceState) { Uri uri = getIntent.getData(); String uriPath = uri.getPath(); if (uriPath.startsWith("/blog/topics")) { // launch Activity for handling topics } else { // launch Activity for handling articles } ! Use a router Activity @gnufmuffin • DevFest Florida, 2016-11-05
  17. App Indexing: How To Implement 4. Index user action To

    get user action indexed (for search autocomplete): — Include App Indexing library dependency — Create Thing for Action — Call AppIndex.AppIndexApi.start() and stop() @gnufmuffin • DevFest Florida, 2016-11-05
  18. App Indexing: How To Implement 4. Index user action Action

    also appears in https://history.google.com/ @gnufmuffin • DevFest Florida, 2016-11-05
  19. What is it? Cross-platform deep linking that survives app installs,

    and drives app installation from mobile web users @gnufmuffin • DevFest Florida, 2016-11-05
  20. What does it give you? — Deep link into app,

    triggers upgrade or install if necessary @gnufmuffin • DevFest Florida, 2016-11-05
  21. What does it give you? — Deep link into app,

    triggers upgrade or install if necessary — Short links @gnufmuffin • DevFest Florida, 2016-11-05
  22. What does it give you? — Deep link into app,

    triggers upgrade or install if necessary — Short links — Analytics @gnufmuffin • DevFest Florida, 2016-11-05
  23. Dynamic Links: How To Implement 1. Create the links —

    Enter basic details in console — Creates a short link @gnufmuffin • DevFest Florida, 2016-11-05
  24. Dynamic Links: How To Implement 1. Create the links —

    Can also construct long links programmatically — ! No analytics — Can create short links programmatically via REST API — From existing long links or from parameters @gnufmuffin • DevFest Florida, 2016-11-05
  25. Dynamic Links: How To Implement 1. Create the links —

    Pass d=1 when creating long link programmatically @gnufmuffin • DevFest Florida, 2016-11-05
  26. Dynamic Links: How To Implement 1. Create the links !

    Cannot delete Dynamic Links at the moment @gnufmuffin • DevFest Florida, 2016-11-05
  27. Dynamic Links: How To Implement 2. Receive links in app

    — Include Dynamic Link library dependency — ! Called firebase-invites — In every activity that could be launched, call AppInvite.AppInviteApi.getInvitation() — MAIN launch activity (if app was just installed) — Any activities with intent filter matching link @gnufmuffin • DevFest Florida, 2016-11-05
  28. Dynamic Links: How To Implement 2. Receive links in app

    — Analytics events automatically generated @gnufmuffin • DevFest Florida, 2016-11-05
  29. Dynamic Links: How To Implement 2. Receive links in app

    You must consume the invitation — ! If you don't, no analytic events will be generated @gnufmuffin • DevFest Florida, 2016-11-05
  30. What is it? Cross-platform messaging service for reliable delivery of

    messages @gnufmuffin • DevFest Florida, 2016-11-05
  31. What does it give you? — Fast, free, and reliable

    message delivery @gnufmuffin • DevFest Florida, 2016-11-05
  32. What does it give you? — Fast, free, and reliable

    message delivery — Display notifications @gnufmuffin • DevFest Florida, 2016-11-05
  33. Comparison with Notifications — Graphical console for re- engagement —

    No coding required — Built-in analytics @gnufmuffin • DevFest Florida, 2016-11-05
  34. Which one? — Notifications — Basic messages meant to be

    displayed — Open rate analytics @gnufmuffin • DevFest Florida, 2016-11-05
  35. Which one? — Notifications — Basic messages meant to be

    displayed — Open rate analytics — Cloud Messaging — Everything else @gnufmuffin • DevFest Florida, 2016-11-05
  36. Cloud Messaging: How To Implement 1. Add messaging service to

    app — Include Cloud Messaging library dependency — Declare messaging service @gnufmuffin • DevFest Florida, 2016-11-05
  37. Cloud Messaging: How To Implement 1. Add messaging service to

    app <service android:name=".notifications.MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> @gnufmuffin • DevFest Florida, 2016-11-05
  38. Cloud Messaging: How To Implement 1. Add messaging service to

    app MyFirebaseMessagingService.java @Override public void onMessageReceived(RemoteMessage remoteMessage) { Map<String, String> data = remoteMessage.getData(); // React to message, e.g. create a Notification, or // schedule sync with server } @gnufmuffin • DevFest Florida, 2016-11-05
  39. Cloud Messaging: How To Implement 2. Subscribe to topics —

    Some uses cases don't require dealing with registration IDs — ! Publish/subscribe model firebase.subscribeToTopic("all_new_articles"); @gnufmuffin • DevFest Florida, 2016-11-05
  40. Cloud Messaging: How To Implement 3. Send message — Send

    message to FCM connection server — From your application server — Manually (e.g. cURL) @gnufmuffin • DevFest Florida, 2016-11-05
  41. Cloud Messaging: How To Implement 3. Send message Example payload:

    { "data": { "article_id": "123400", "notif_type": "new_article" }, "to" : "/topics/all_new_articles", "restricted_package_name": "com.example" } @gnufmuffin • DevFest Florida, 2016-11-05
  42. Cloud Messaging: How To Implement 3. Send message Example cURL

    invocation: curl \ --header "Authorization: key=${FCM_SERVER_KEY}" \ --header "Content-Type: application/json" \ https://fcm.googleapis.com/fcm/send \ --data-ascii "${BODY}" @gnufmuffin • DevFest Florida, 2016-11-05
  43. Cloud Messaging: How To Implement 3. Send message — !

    Understand data vs notification messages — Default behaviour may not be what you want @gnufmuffin • DevFest Florida, 2016-11-05
  44. What is it? Change behaviour and appearance of app without

    needing a client update @gnufmuffin • DevFest Florida, 2016-11-05
  45. What does it give you? — Tune parameters in app

    — Appearance — Timing @gnufmuffin • DevFest Florida, 2016-11-05
  46. What does it give you? — Tune parameters in app

    — Appearance — Timing — Run experiments, A/B tests @gnufmuffin • DevFest Florida, 2016-11-05
  47. Remote Config Overview — Single access point for storing config

    data @gnufmuffin • DevFest Florida, 2016-11-05
  48. Remote Config Overview — Single access point for storing config

    data — Client handles fetching, caching, and activating remote config @gnufmuffin • DevFest Florida, 2016-11-05
  49. Remote Config Overview — Single access point for storing config

    data — Client handles fetching, caching, and activating remote config — Use console to define parameters, with optional conditions @gnufmuffin • DevFest Florida, 2016-11-05
  50. Remote Config: How To Implement 1. Set up default values

    in app — Include Remote Config library dependency — Define parameter names and values in defaults.xml @gnufmuffin • DevFest Florida, 2016-11-05
  51. Remote Config: How To Implement 1. Set up default values

    in app <defaultsMap> <entry> <key>sync_min_seconds</key> <value>300</value> </entry> <entry> <key>sync_max_seconds</key> <value>1500</value> </entry> <entry> <key>Experiment_notif_title</key> <value>notif_title_default</value> </entry> </defaultsMap> @gnufmuffin • DevFest Florida, 2016-11-05
  52. Remote Config: How To Implement 1. Set up default values

    in app — Apply defaults to Remote Config remoteConfig.setDefaults(R.xml.defaults); @gnufmuffin • DevFest Florida, 2016-11-05
  53. Remote Config: How To Implement 1. Set up default values

    in app — Read from config in your app long seconds = remoteConfig.getLong("sync_min_seconds"); String variant = remoteConfig.getString("Experiment_notif_title"); @gnufmuffin • DevFest Florida, 2016-11-05
  54. Remote Config: How To Implement 2. Set up server values

    @gnufmuffin • DevFest Florida, 2016-11-05
  55. Remote Config: How To Implement 2. Set up server values

    @gnufmuffin • DevFest Florida, 2016-11-05
  56. Remote Config: How To Implement 3. Set up experiments Conditions

    are used to target groups of users — User property, device property, audience, random percentile @gnufmuffin • DevFest Florida, 2016-11-05
  57. Remote Config: How To Implement 3. Set up experiments e.g.

    A/B test with equal buckets @gnufmuffin • DevFest Florida, 2016-11-05
  58. Remote Config: How To Implement 3. Set up experiments Define

    parameter values for each condition @gnufmuffin • DevFest Florida, 2016-11-05
  59. Remote Config: How To Implement 4. Fetch remote config in

    app remoteConfig.fetch(cacheExpiration) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { remoteConfig.activateFetched(); // or, activate whenever appropriate } } }); @gnufmuffin • DevFest Florida, 2016-11-05
  60. Remote Config: How To Implement 4. Fetch remote config in

    app — Record variant as user property — Use to define Analytics audience analytics.setUserProperty("Experiment_notif_title_variant", remoteConfig.getString("Experiment_notif_title")); @gnufmuffin • DevFest Florida, 2016-11-05
  61. Review — App Indexing: Gets app into Google search results

    — Dynamic Links: Deep linking that survives app installs and drives re-engagement — Cloud Messaging: Service for reliable delivery of messages — Remote Config: Change behaviour and appearance of app after deploy @gnufmuffin • DevFest Florida, 2016-11-05
  62. Further Reading App Indexing — https://firebase.google.com/docs/app-indexing/ — https://developer.android.com/training/app-links/ index.html —

    https://realm.io/news/juan-gomez-android-app- indexing/ — https://moz.com/blog/how-to-get-your-app-content- indexed-by-google @gnufmuffin • DevFest Florida, 2016-11-05
  63. Additional Resources (1/2) — Dev Summit: Nov 7 in Berlin:

    https:// events.withgoogle.com/firebase-dev-summit/ — Status Dashboard: https:// status.firebase.google.com/ — Google Group: https://groups.google.com/forum/#! forum/firebase-talk — Slack: https://firebase-community.appspot.com/ @gnufmuffin • DevFest Florida, 2016-11-05
  64. Additional Resources (2/2) — Blog: https://firebase.googleblog.com/ — YouTube channel: https://www.youtube.com/

    channel/UCP4bf6IHJJQehibu6ai__cg — SDK Changelog: https://firebase.google.com/ support/releases — Quickstart samples: https://github.com/firebase/ quickstart-android @gnufmuffin • DevFest Florida, 2016-11-05
  65. Let's have some questions! Email [email protected] Work www.shopify.com Twitter @gnufmuffin

    Slides speakerdeck.com/efung/ Blog code.gnufmuffin.com @gnufmuffin • DevFest Florida, 2016-11-05