App Actions deployment requirements

To ensure that users enjoy a seamless experience when using App Actions, you must meet these requirements before activating App Actions for your app:

  • Report App Action interaction results: To help Google proactively suggest your App Actions to users, use the Firebase App Indexing API to let the Assistant know whether your app has successfully handled a built-in request.
  • Handle the ACTION_SEARCH Android intent: If your app has a search function, you must support the ACTION_SEARCH common intent. This lets Google provide a fallback mechanism if we are unable to resolve the user's query to a built-in intent.

These requirements are described in more detail below.

Report interaction results

Google monitors the health of your App Actions to know when they aren't working as intended. You must let Google know using Firebase whether your app successfully handled a built-in intent with App Actions.

To satisfy this requirement, take these steps in your Android app:

  1. Add Firebase and the App Indexing library to your Android Studio project.
  2. For deep-linked activities launched via App Actions, use the FirebaseUserActions class to report either that the App Action invocation was handled by your app successfully or that it was not.

    For example, a user uses App Actions to order soup from a soup provider. The user is deep linked to a confirmation page prior to adding the soup to a cart. At this point, the app reports a success via FirebaseUserActions.

    As another example, a user uses App Actions to order soup from a provider who can't fulfill their request (like a shoe store). The app only supports deep links for items in inline inventory. When the deep link handler runs, the app reports a failure via FirebaseUserActions.

    Note that if this app handled the absence of the desired item with a fallback search for the string in inventory, the app would have reported a success instead.

You can tell that an activity was launched via App Actions if the incoming deep link matches the format of a URL template defined in your actions.xml file. Because you define both the URL template and how an activity handles deep links, you can flag and recognize deep links from App Actions in a way that best suits your app.

For example, in your actions.xml file, you can add a query string parameter to the URL template of the <fulfillment> element. In the corresponding activity, you can then look for that parameter to determine whether a user triggered the deep link via App Actions.

The following code snippet shows how to use the FirebaseUserActions class to report status when users invoke your App Actions:

Java
private static final String ACTION_TOKEN_EXTRA =
        "actions.fulfillment.extra.ACTION_TOKEN";

void notifyActionStatus(String status) {
  String actionToken = getIntent().getStringExtra(ACTION_TOKEN_EXTRA);
  final Action action = new AssistActionBuilder()
          .setActionToken(actionToken)
          .setActionStatus(status)
          .build();
  FirebaseUserActions.getInstance().end(action);
}

// On Action success
notifyActionStatus(Action.Builder.STATUS_TYPE_COMPLETED);

// On Action failed
notifyActionStatus(Action.Builder.STATUS_TYPE_FAILED);
      
Kotlin
private val actionTokenExtra = "actions.fulfillment.extra.ACTION_TOKEN"

fun notifyActionStatus(status: String) {
    val actionToken = intent.getStringExtra(actionTokenExtra)
    val action = AssistActionBuilder()
            .setActionToken(actionToken)
            .setActionStatus(status)
            .build()
    FirebaseUserActions.getInstance().end(action)
}

// On Action success
notifyActionStatus(Action.Builder.STATUS_TYPE_COMPLETED)

// On Action failed
notifyActionStatus(Action.Builder.STATUS_TYPE_FAILED)
      

Make sure that you're uploading the action data to Google servers (default behavior) by not setting setUpload(false).

You can verify that the correct logs are being reported by doing the following:

  1. In Android Studio, open the App Actions test tool and create a preview of your App Actions. If you've already created a preview, update your preview instead.
  2. On your test device, enable developer options if not already enabled.
  3. In the Settings app, select Google, then Firebase App Indexing.
  4. Toggle Capture User Actions and Errors to On.
  5. Trigger your App Action intent on your test device via the Assistant or the App Actions test tool.
  6. Return to the Firebase App Indexing page of the Settings app and select your app.

  7. Verify that the AssistAction user action contains items for actionToken and actionStatus.

  8. Verify that the actionStatus item contains the status corresponding to success or failure of the triggered built-in intent. Validate your Firebase logging separately for successes and failures.

The actionStatus and actionToken items are highlighted in a device screenshot of the User Action Details page.

In the event where the Assistant is confident that the user wishes to access your app via the Assistant, but is unable to resolve the query to a built-in intent, it's important to provide a fallback mechanism. If your app already has a search function, you must handle the ACTION_SEARCH Android intent, so that Google can pass the user query into your app, if needed.

The following snippet shows how to add an intent filter to an Activity with the ACTION_SEARCH common intent in the AndroidManifest.xml file:

<activity android:name=".SearchActivity">
    <intent-filter>
        <action android:name="com.google.android.gms.actions.SEARCH_ACTION"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

In your search activity, you should check the for the ACTION_SEARCH intent and extract the query. Then, do something with the query like running a search and displaying the results in the UI. For example, you could make a query to the Assistant like this: "Hey Google, show me cats on myvideoapp".

The following code snippet shows an example implementation.

Java
@Override
protected void onCreate(Bundle savedInstanceState) {
...
  Intent intent = getIntent();
  if (intent.getAction().equals(SearchIntents.ACTION_SEARCH)) {
    String query = intent.getStringExtra(SearchIntents.EXTRA_QUERY);
    //TODO: user query value to run search
  }
}
      
Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    ...
    if (intent?.action == SearchIntents.ACTION_SEARCH) {
        val query = intent?.getStringExtra(SearchIntents.EXTRA_QUERY)
        // TODO: use query value to run search
    }
    ...
}
      

To learn more about handling this common intent, see the Search using a specific app guide in the Android documentation.