Some gotchas when using Firebase Dynamic Links

The last couple of weeks I have been trying to add Firebase Dynamic Links into an app and it took me way longer than I had originally planned. In this post, I wanted to share some of the lessons learned.

First: note that there are 2 kinds of links that you can use:

  1. Dynamic links that you generate on the Dynamic Links section of your Firebase project. These will be the same for every user and are great to link to universally same sections of your app. These are quick to set up and are probably a good idea to try before generating the second kind of deep links
  2. Dynamic links generated by a user for another user on a client application. These would be custom links only relevant for unique users and so cannot be generated via the project dashboard.

In my case, I was trying to get #2 working and it proved to be a real bear.

The problem is that when generating a unique URL, you are essentially doing a couple of handoffs: The first link is managed completely by Firebase (usually with a *.page.link URL). This link checks to see if the app is installed on the device the link is launched on and links to the app-install page if not. If that is fine, the link redirects to the second link that you actually are trying to get to. The second link is often a web address on your own domain which needs to be correctly configured for that page, or else the link will just open that webpage which is probably not what you want to do.

Gotcha 1: [Android] Make sure you have the SHA256 signature saved in your Firebase project

For the longest time, I didn’t realize that I had only the SHA1 key saved in my project. Deep links don’t work without SHA256 values for your project. Thanks to this answer from StackOverflow.

It took me a while to get this document correctly deployed (mostly my fault). I really should have read the documentation on verified site associations on Android more carefully. You can verify your assetlinks setup via this URL (just replace the domain and, if applicable, port values):

https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://domain1:port&relation=delegate_permission/common.handle_all_urls

Also remember, if you are using Google Play Store to sign and release your app, your assetlinks should refer to their key’s SHA256 signatures. Conveniently, you can copy the assetlinks file from the Play Store itself under the Setup > App Integrity section of the developer console

Gotcha 3: [Android] Make sure “autoverify” attribute in your intent-filter is set to true

Not sure how I missed this but, this took a long time to find

 <intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
     <category android:name="android.intent.category.BROWSABLE" />
     <data
          android:scheme="https"
          android:host="my.app.com" />
 </intent-filter>

iOS:

Surprisingly, as frustrating as getting the Android version to work was, the iOS integration was much simpler. Just following this video helped a lot!

Hope some of this info helps you if you are using dynamic links in your app

Jetpack Compose: Rocketing in the right direction

Jetpack Compose Logo

Last week was Labweek at Comcast, one of the best traditions at Comcast, where developers and designers can take some time to pursue ideas, learn new technologies or just work with folks you don’t usually get to work with. Though every week can be labweek in my world working at Comcast Labs, I still enjoy working on something completely different from the projects-on-record for a week. You can read about a few of my previous labweek prototypes here.

For this labweek, I took the opportunity to build something with Jetpack Compose, Google’s new UI toolkit for building Android apps. In the last couple of years I have worked quite a bit with ReactJS, SwiftUI and a LOT with Flutter (read my thoughts on Flutter here) , and it was interesting to see how all of them were starting to adopt the same patterns. From the sessions at IO and conversations at the Philadelphia Google Developers’ Group that I help run, I knew Jetpack was also headed the same direction, but it took me building an app to realize how close that was.

Compose vs. SwiftUI

Compose feels the closest to SwiftUI, borrowing not only the ideas of light weight layout containers (Rows, Columns, etc) but also the use of Modifiers to manipulate the View …sorry…the Composable. Even the structure of a typical compose file with a function that defines your composable and another, annotated with a preview annotation, that lets you preview your layout is identical to the SwiftUI edit/preview experience. The similarity even extends to the documentation experience: check out the SwiftUI tutorial and the Compose tutorial page layouts with text on left that scrolls with the code on the right. Heck, even my bugs are similar in both frameworks 😉

Compose vs. Flutter

While Flutter is similar to Compose, I do prefer Compose’s modifier approach to Flutter’s approach of composing behavior using a hierarchy of widgets, though the hot reload on a device/simulator that Flutter does is preferred to the preview experience on Compose, specially since previews cannot fetch live data from the cloud and my design was very remote image heavy.

I also find creating animations in Flutter a bit cumbersome, having to create AnimationControllers, TickerProviderMixins, Curves and callbacks. Jetpack Compose does seem to have enough complexity in their own system as well but I got a lot of mileage out of just using AnimatedVisibility with enter and exit animations, though SwiftUI with the `withAnimation` blocks is the clear winner here.

Flowchart describing the decision tree for choosing the appropriate animation API
Compose’s animation system isn’t lacking in complexity either

Random Lessons Learned

There were a couple of gotchas as I was building the app: For some functionality that I would consider core, like fetching remote images or making your app aware of things like WindowInsets, is only available as part of an external (Google authored) library called Accompanist. I had a bit of a hiccup because my version of that library wasn’t compatible with the version of Jetpack in my Android IDE. I do hope these capabilities get added to Jetpack Compose core instead of an external dependency that I’d have to track (I do prefer the batteries included approach). Also if you do plan to use the official samples as a starting point, note that some (or at least the one we were using) has a compiler instruction to fail on all warnings (that took like 2 hours to figure out)

Wrapping Up

A week of intense coding in compose gave me a lot of appreciation for this new direction for Android development. I was pleasantly surprised how productive I felt working on a completely custom Android UI. There is still a lot of features of Compose I haven’t tried out yet but am definitely looking forward to learning more. At this moment Compose is not officially out yet (the latest version is release candidate 1 that came out a few days ago), but I am sure Compose will enable some truly amazing UI experiences on Android in the next few months!

Adding React Native to an existing Android App

After my recent adventures with ReactJS, I have been thinking of playing around a bit with React Native. I have looked at it before and even gave a talk on a previous version of it at a previous AndroidPhilly event.  Instead of trying a new React Native app, I figured it might be a good idea to maybe try it on an Android app I am already developing (more on that later). Instagram recently wrote an interesting article on adding React Native to their existing app so I was glad there was a migration path for native apps that didn’t involve starting a React Native app from scratch.

Let go

laptop

The React Native site has a fairly good walkthrough on adding RN to a native app. I did as instructed (I think) and mostly things went ok. And then, the expected issues began.

So long Jack

Hitting compile on AndroidStudio seemed to work for a bit and then it would just hang. Not getting anything useful there, I tried to compile the app from the command line using

./gradlew installDebug

What I saw was that the process would get stuck at a compile with Jack process. Jack was a new toolchain Google was building for Android development and I was the way to use some Java 8 features on current devices. However this month Google announced they were moving away from Jack and fortunately, my app barely used it. So I decided to remove Jack from the app altogether. That worked and AndroidStudio compiled and packaged the app and I got my app running on the emulator! It looked like…

js

Wherefore art the JS Bundle

This seemed to be an simple network issue with the emulator not seeing the locally running server. Having dealt with this while trying to get the emulator to see a locally running rails api, I figured it was something simple. React Native comes with a build it settings activity that you can call by rage-shaking the device or executing

adb shell input keyevent 82

which brings up the options menu that you can then use to launch the Settings Activity.

Wrong Settings

…except that doing that launched my apps preferences screen. Turns out React Native was just looking for a file named preferences.xml file and launching that. It just happens my app’s preferences screen was also defined by the xml file with the same name and so there was a conflict. Changing my apps preference.xml file name got around that.

Crash

I changed the ip address on React Native’s debug screen and went back to the main activity only to have the app crash. Looking at Logcat, I got this weird error

Caused by: java.lang.IllegalAccessError: 
Method 'void android.support.v4.net.ConnectivityManagerCompat.()' 
is inaccessible to class 'com.facebook.react.modules.netinfo.NetInfoModule' 
(declaration of 'com.facebook.react.modules.netinfo.NetInfoModule' 
appears in /data/app/*****.debug-2/base.apk)
     at com.facebook.react.modules.netinfo.NetInfoModule.(NetInfoModule.java:55)
     at com.facebook.react.shell.MainReactPackage.createNativeModules(MainReactPackage.java:67)
     at com.facebook.react.ReactInstanceManagerImpl.processPackage(ReactInstanceManagerImpl.java:793)
     at com.facebook.react.ReactInstanceManagerImpl.createReactContext(ReactInstanceManagerImpl.java:730)
     at com.facebook.react.ReactInstanceManagerImpl.access$600(ReactInstanceManagerImpl.java:91)
     at com.facebook.react.ReactInstanceManagerImpl$ReactContextInitAsyncTask.doInBackground(ReactInstanceManagerImpl.java:184)

Oh weird. Going by this thread, it looked like an API change in Play Services recently was causing an issue. But hold on, according to the conversation, the issue was fixed in RN v22. What the heck was I using?

Listing dependencies with gradlew

I didn’t know this but you can actually list your exact dependency tree by calling

./gradlew app:dependencies

which gives you a nice dependency tree that looks like

Screen Shot 2017-03-29 at 1.05.06 AM

Since the dependency stated in my build.gradle was just

compile "com.facebook.react:react-native:+"

it could be satisfied by any instance of RN gradle found on Maven Central. Except that one of the steps in setting up the project included defining the local folder in node_modules that held the latest (0.43 at the time of writing) and the only version on Maven Central was old (0.20). Turns out (after about an hour of pulling my hair out) that there was an error in the file path I had used to identify the node_module location and setting it right fixed the final issue.

Viola!

4 hours of dev or so and my app finally launched its hello world React Native screen alongside the native activities. Not too bad, I was expecting worse, given all the new tools in play. Lets hope this is worth it.


Tip:

Btw, unlike developing React for the web (using CreateReactApp), the console that you use to launch the dev server does not show the log messages. To see your app logs, use

reactnative logandroid

 

Presentation: Introduction to React Native for Android

Last week I gave a quick presentation at Android Alliance Philly on React Native, Facebook’s new framework that lets you develop native mobile apps using JavaScript and JSX, a layout language modeled after HTML and CSS. The deck is embedded below:

All source code for the example project can be found on Github

Thanks to all who came out to the event.

UI Concept: Using Android’s Soft Keys for Screen Pinning

I have written before on how Android could be using their software navigation buttons more appropriately. Seeing how Android 5.0 and 5.1 handle screen pinning seems another one of those situations where it could leverage that capability.

For those unaware of the feature, Android 5.0 introduced a feature that allowed you to pin a certain application to the home screen. The primary use case for this feature is to prevent a child or some one you hand over your phone to to accidentally exit an app that you want them to see/use. Since the feature doesn’t require a pin number to exit the app, the feature is not so much designed for security but rather for preventing accidents. Exiting the pinned app requires you to tap the “Back” and the “Overview” screen at the same time. A feature that people may forget (though the OS does bring up a message if you do tap any of the navigation buttons when a screen is pinned). This is probably what prompted a more explicit how-to view explaining the exit action in Android 5.1.

However this feature once again doesn’t take into account the Android soft keys. When a screen is pinned, why not change the graphics for Back and Overview to pin icons. This would also reinforce the fact that the phone is in a separate “pinned screen” mode.

screen-pin

As always, thoughts are welcome 🙂

Announcing Artbook: An Android Client for Dribbble

I am a big fan of Dribbble. For the uninitiated, its a community for designers to share parts of their work and is pretty inspirational when you are thinking of designs for your own applications. When I released FreeFlow earlier this year, I included a sample Dribbble project as part of the release to showcase the power of layout system. Since then I recieved a couple of messages from a few folks to just complete that as an app since a lot of the work was already done anyway. It also didn’t seem like there were any really compelling Dribbbble apps on the Play Store (well none that I felt were very interesting anyway). So last week I worked a bit and finished the Artbook app

Like the original source that was included in FreeFlow, Artbook is completely open source and released under the Apache 2 license. The code for the app has some ugly parts but is generally okay. Having recently acquired a 10.1” Android tablet (the Galaxy Note 10.1 mostly for drawing), I really wanted to make sure it had a fantastic tablet experience. However unlike Google’s direction to use Fragments for multi device layouts, this app does it via just a few simple if-else blocks and conditionally loading layouts. I find this approach so much simpler than any elaborate Fragment based architectures.

Anyway, I hope you give it a shot and see if you like it. I find browsing Dribbble a lot more fun using it

 

Improving Android’s NavigationBar

One of the interesting features that were released as part of Android 3.0 HoneyComb release back in 2011 was the introduction to the soft navigation buttons. To me, the system seemed full of potential as navigation buttons adapted to better educate the user as the user used the system. For example, while using an application, if the user ended up launching the keyboard, the back button would change to indicate that back would now just dismiss the keyboard and not actually go back to the previous screen.

keyboard

 

Three years later, I am surprised that not much else was added. The back navigation while powerful still can get ambiguous at times. Below are a couple of ideas I think can really improve the user experience on Android today.

Preventing accidental over-backing

Accidentally hitting back one too many times is a problem that I encounter enough times that it really does get irritating. I am sure it happens to other app developers as well, which is why often you see developers implementing the extremely frowned upon “Are you sure you want to exit” modal alert in apps.

The soft button could really fix this problem by changing itself to indicate that you are at the last item in a stack. I am not an icon designer but here is how I imagine the soft keys changing when the user is on the only activity in the stack. The icon clarifies that hitting that button will exit the activity.

app-close

 

 

Enabling Done Discard Pattern

The constant presence of a back button causes confusion in one other place: when a user is modifying data, like adding a todo item on a list or adding a new contact. Without an explicit tap on a save button, hitting back or tapping on the Home icon now adds ambiguity to the question of whether the user wanted to save the data or not. One of the nicer patterns that emerged in Android was the Done/Discard pattern that Roman Nurik released as an Android library a while back, but because it doesn’t prevent the back button, a better way was if Android introduced a “Done Discard Activity” that would modify the back button and maybe temporarily hide the multitasking action.

done-discard

 

What do you think? How else could the the digital nature of the Android navigation bar be used to improve Android UX?

Big in China

I haven’t looked at the usage stats for PicScribe in a while. It does the couple of things I need it for and I am mostly content with the functionality. But with Material Design I was thinking of giving the app a refresh as well as add some features I had been meaning to as well.

Looking at the stats today was interesting though. Looking at my integrated Google Analytics data, it appears that majority of the app usage is happening in China where Google Play doesn’t even exist. I have no idea how they got the app, its free so it doesn’t matter, but still.

china.png
All the top phones are also local ones (mostly Xiaomi ).

Lesson of the day: Make sure you add analytics to your app.

 

 

 

Android wishlist: A different notification UI for background services

This post is first in a series around enhancements to the mobile experience I’d like to see going forward. Stay tuned for more 🙂

Background services are one of my favorite features on Android. As the idea of a smartphone changes from a phone to a true contextual device, background services that keep track of user context and push information to the user at appropriate times are essential. That said, the current visual treatment they get on the device to let a user know that they are running, which hasn’t changed much since the inception of Android, needs to change.

The Problem

Here is a screenshot of my notification shade right now. Note that only one of the 8 notifications I am currently seeing is actually a new event that I actually need to respond to. The flooding of my notification window with the always running service notifications numbs me to actually important actionable notification that sits there.

2014-05-10 12.59.31

 

Proposed Solution Option 1:  Notification Tabs with services tucked away

A lot of ROMs already implement Notification Tabs. Moving the background services to a separate tab so that I don’t have to look at them whenever I pull down the shade would solve the problem, though it does add some complexity to the shade.

2014-05-10 12.45.32

 

 

Proposed Solution Option 2: Collapse background service notifications into one low-priority notification:

This option may be a little better since you don’t add the cognitive complexity to the notifications shade. Simple is better usually 🙂

2014-05-10 13.35.20

Final thoughts:

In both the cases above developers will have to explicitly change their own notification priority to escape the “grouping”. So if a significant event occurs, their notification can be shown along with the rest of the notifications.

As notifications become increasingly more important to the mobile experience, like the coming smart watches that are all about contextual notifications sent by your phone, there is a greater need to make sure that we don’t overwhelm the user with an unorganized stream of information.

As always, feedback is most welcome 🙂