Enable Personal Content Indexing

With personal content indexing, your app provides search results in the Google app for content tied to a user's account. Users only see their own personal content on their devices.

For example, if a user searches for "favorite chicken recipe," the In Apps results tab includes the note they added to a chicken recipe in the recipe app.

If your app doesn't include any personal content, you can skip this step and go straight to Log User Actions.

Before you start, make sure you support links to your app content and have added the App Indexing library to your app.

Establish the index and add objects

Create a class that extends the JobIntentService. The implementation outlined in this doc relies on the JobIntentService class to queue the updates to the on-device index, but you can use an alternative class to schedule the work. If you do follow the implementation using the JobIntentService class, make sure to also add the Android Support Library to your project's build.gradle file.

Then, to include items in the app's personal content index, create Indexable objects in the same class:

package com.example.myapp;

import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v4.app.JobIntentService;
import com.google.firebase.appindexing.builders.Indexables;
import com.google.firebase.appindexing.FirebaseAppIndex;
import com.google.firebase.appindexing.Indexable;
import java.util.ArrayList;

public class AppIndexingUpdateService extends JobIntentService {
  // Job-ID must be unique across your whole app.
  private static final int UNIQUE_JOB_ID = 42;

  public static void enqueueWork(Context context) {
    enqueueWork(context, AppIndexingUpdateService.class, UNIQUE_JOB_ID, new Intent());
  }

  @Override
  protected void onHandleWork(@NonNull Intent intent) {
    // TODO Insert your Indexable objects — for example, the recipe notes look as follows:

    ArrayList<Indexable> indexableNotes = new ArrayList<>();

    for (Recipe recipe : getAllRecipes()) {
        Note note = recipe.getNote();
        if (note != null) {
            Indexable noteToIndex = Indexables.noteDigitalDocumentBuilder()
                    .setName(recipe.getTitle() + " Note")
                    .setText(note.getText())
                    .setUrl(recipe.getNoteUrl())
                    .build();

            indexableNotes.add(noteToIndex);
        }
    }

    if (indexableNotes.size() > 0) {
        Indexable[] notesArr = new Indexable[indexableNotes.size()];
        notesArr = indexableNotes.toArray(notesArr);

        // batch insert indexable notes into index
        FirebaseAppIndex.getInstance().update(notesArr);
    }
  }


What should be in the personal content index?

Define Indexable objects for the following types of content:

  • User-specific content, like messages, photos, or documents.
  • Content that's important to users, such as favorites or content that they may want to access more frequently. For example, documents or songs that they've bookmarked or marked for offline use.
  • Content generated in your app, not just accessed by it. For example, contacts that are created by users directly in your app, and stored by your app, not contacts from the phone's directory.

Add a broadcast receiver to your app

Google Play Services periodically sends a request to your app to update the on-device index. The BroadcastReceiver class receives this request and triggers the JobIntentService to process the indexing work. The example below uses the AppIndexingUpdateService class from the previous step.

package com.example.myapp;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.google.firebase.appindexing.FirebaseAppIndex;

/** Receives broadcast for App Indexing Update. */
public class AppIndexingUpdateReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    if (intent != null
        && FirebaseAppIndex.ACTION_UPDATE_INDEX.equals(intent.getAction())) {
      // Schedule the job to be run in the background.
      AppIndexingUpdateService.enqueueWork(context);
    }
  }
}

Generate and refresh the index

Next, allow Google Play services to call the App Indexing service to update the on-device index with the user's personal content in the following three situations:

  • When the app is installed on a device.
  • If an existing version of the app is updated to a version that supports personal content indexing.
  • Periodic calls over time to accurately reflect any changes that happen to the indexed content, ensuring a seamless user experience.

Additionally, if the on-device index is lost for any reason (e.g., if the index is corrupted), this call to update the index will repopulate it.

In your AndroidManifest.xml file, register the BroadcastReceiver so it can receive calls from Google Play Services to update the index. The example below uses the JobIntentService class to schedule the indexing updates:

<!-- Register the BroadcastReceiver -->
<receiver android:name=".AppIndexingUpdateReceiver"
         android:exported="true"
         android:permission="com.google.android.gms.permission.APPINDEXING">
    <intent-filter>
        <action android:name="com.google.firebase.appindexing.UPDATE_INDEX" />
    </intent-filter>
</receiver>

<!-- Grant the AppIndexingUpdateService permission and enable it to run after being triggered -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<service android:name=".AppIndexingUpdateService"
         android:permission="android.permission.BIND_JOB_SERVICE" />

Update the index

When users add, update, or remove their personal content, the on-device index should reflect those changes. Add the following code to update content in the index:

Add & update
private void indexNote() {
        Note note = mRecipe.getNote();
        Indexable noteToIndex = Indexables.noteDigitalDocumentBuilder()
                .setName(mRecipe.getTitle())
                .setText(note.getText())
                .setUrl(mRecipe.getNoteUrl())
                .build();

        Task<Void> task = FirebaseAppIndex.getInstance().update(noteToIndex);
         ...
    }
    
Remove

To identify items that should be removed, use the URL of the item. Add the following line to your app’s delete or remove function for that item.

                    // Deletes or removes the corresponding notes from index.
                    String noteUrl = mRecipe.getNoteUrl();
                    FirebaseAppIndex.getInstance().remove(noteUrl);
         

Delete the index when users log out

Delete the on-device index when users log out of your app, on the logout event. Include the call to generate and refresh the index using AppIndexingService to repopulate the on-device index when users log in again.

To delete the on-device index when a user logs out of your app, add the following code to your app:

...
import com.google.firebase.appindexing.FirebaseAppIndex;

public class LogOutActivity extends Activity {
    ...
    private void onLogOutButtonClicked() {
        ...
        FirebaseAppIndex.getInstance().removeAll();
    }
}

Next: Log User Actions

Send feedback about...

Need help? Visit our support page.