{"id":1438,"date":"2026-06-13T13:00:00","date_gmt":"2026-06-13T18:00:00","guid":{"rendered":"https:\/\/tolinku.com\/blog\/?p=1438"},"modified":"2026-03-07T03:49:14","modified_gmt":"2026-03-07T08:49:14","slug":"firebase-app-indexing","status":"publish","type":"post","link":"https:\/\/tolinku.com\/blog\/firebase-app-indexing\/","title":{"rendered":"Firebase App Indexing: What Replaced It and How to Migrate"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Firebase App Indexing was Google&#39;s recommended way to surface Android app content in search results. It was part of the Firebase platform and worked alongside Firebase Dynamic Links to connect web content with in-app destinations. In August 2025, Google shut down Firebase Dynamic Links, and Firebase App Indexing went with it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you relied on Firebase App Indexing, your app content may have lost search visibility. This guide explains what Firebase App Indexing did, what has replaced it, and how to migrate. For the broader Firebase shutdown migration, see <a href=\"https:\/\/tolinku.com\/blog\/firebase-dynamic-links-shutdown\/\">Firebase Dynamic Links shutdown<\/a>. For the step-by-step migration, see <a href=\"https:\/\/tolinku.com\/blog\/migrate-from-firebase-dynamic-links\/\">Firebase Dynamic Links migration guide<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Firebase App Indexing Did<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Firebase App Indexing provided two capabilities:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. App Indexing API<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/firebase.google.com\/docs\/app-indexing\" rel=\"nofollow noopener\" target=\"_blank\">App Indexing API<\/a> let your app tell Google about content the user viewed. When a user opened a product page in your app, your app called the API to report the view:<\/p>\n\n\n\n<pre><code class=\"language-kotlin\">\/\/ Old Firebase App Indexing code\nimport com.google.firebase.appindexing.FirebaseAppIndex\nimport com.google.firebase.appindexing.Indexable\n\nclass ProductActivity : AppCompatActivity() {\n    override fun onStart() {\n        super.onStart()\n\n        val indexable = Indexable.Builder()\n            .setName(&quot;Product Name&quot;)\n            .setUrl(&quot;https:\/\/www.yourapp.com\/products\/123&quot;)\n            .build()\n\n        FirebaseAppIndex.getInstance(this).update(indexable)\n    }\n\n    override fun onStop() {\n        super.onStop()\n        FirebaseAppIndex.getInstance(this).remove(&quot;https:\/\/www.yourapp.com\/products\/123&quot;)\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This API reported viewed content to Google, which could then surface it in search results for other users.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. Automatic Deep Link Handling<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Firebase App Indexing integrated with Firebase Dynamic Links to handle incoming deep links from search results. When a user tapped an app result in Google Search, Firebase handled the URL routing:<\/p>\n\n\n\n<pre><code class=\"language-kotlin\">\/\/ Old Firebase deep link handling\nFirebaseDynamicLinks.getInstance()\n    .getDynamicLink(intent)\n    .addOnSuccessListener { pendingDynamicLinkData -&gt;\n        val deepLink = pendingDynamicLinkData?.link\n        if (deepLink != null) {\n            navigateToContent(deepLink)\n        }\n    }\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With Dynamic Links shut down, this code no longer works.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Replaced Firebase App Indexing<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Google did not provide a direct 1:1 replacement. Instead, the functionality is split across several systems:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Android App Links (Replaces Deep Link Handling)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/developer.android.com\/training\/app-links\" rel=\"nofollow noopener\" target=\"_blank\">Android App Links<\/a> are the standard way to handle HTTPS deep links on Android. They existed before Firebase App Indexing and continue to work independently:<\/p>\n\n\n\n<pre><code class=\"language-xml\">&lt;intent-filter android:autoVerify=&quot;true&quot;&gt;\n    &lt;action android:name=&quot;android.intent.action.VIEW&quot; \/&gt;\n    &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; \/&gt;\n    &lt;category android:name=&quot;android.intent.category.BROWSABLE&quot; \/&gt;\n    &lt;data android:scheme=&quot;https&quot;\n          android:host=&quot;www.yourapp.com&quot;\n          android:pathPrefix=&quot;\/products&quot; \/&gt;\n&lt;\/intent-filter&gt;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">App Links require hosting a <a href=\"https:\/\/developers.google.com\/digital-asset-links\/v1\/getting-started\" rel=\"nofollow noopener\" target=\"_blank\">Digital Asset Links<\/a> file (<code>assetlinks.json<\/code>) on your domain.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Web Markup + Search Console (Replaces App Indexing API)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The App Indexing API&#39;s function (telling Google about in-app content) is now handled by web-side markup:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Structured data<\/strong> on your web pages declares that app alternatives exist.<\/li>\n<li><strong>Alternate link tags<\/strong> point to your Android app.<\/li>\n<li><strong>Search Console<\/strong> verifies the web-app connection.<\/li>\n<\/ol>\n\n\n\n<pre><code class=\"language-html\">&lt;!-- Web page markup that replaces App Indexing API --&gt;\n&lt;link rel=&quot;alternate&quot; href=&quot;android-app:\/\/com.yourapp.android\/https\/www.yourapp.com\/products\/123&quot; \/&gt;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">See <a href=\"https:\/\/tolinku.com\/blog\/google-app-indexing-setup\/\">Google App Indexing setup<\/a> for the full implementation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Third-Party Deep Linking Platforms (Replaces Dynamic Links)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For the deep link creation, routing, and analytics that Firebase Dynamic Links provided, third-party platforms fill the gap. <a href=\"https:\/\/tolinku.com\/features\/deep-linking\">Tolinku<\/a> handles the infrastructure: custom domains, verification file hosting, route configuration, and deep link analytics.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Migration Steps<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Remove Firebase App Indexing SDK<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Remove the Firebase App Indexing dependency from your project:<\/p>\n\n\n\n<pre><code class=\"language-gradle\">\/\/ Remove from build.gradle\n\/\/ implementation &#39;com.google.firebase:firebase-appindexing:20.0.0&#39;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Remove all <code>FirebaseAppIndex<\/code> and <code>Indexable<\/code> code from your Activities.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Set Up Android App Links<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you were relying on Firebase Dynamic Links for deep link handling, switch to Android App Links:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add intent filters to your <code>AndroidManifest.xml<\/code> for each content type your app handles.<\/li>\n<li>Host <code>assetlinks.json<\/code> on your domain (or use a platform like Tolinku that hosts it automatically).<\/li>\n<li>Handle incoming intents in your Activities.<\/li>\n<\/ol>\n\n\n\n<pre><code class=\"language-kotlin\">class ProductActivity : AppCompatActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        val uri = intent.data ?: return\n        val productId = uri.lastPathSegment ?: return\n        loadProduct(productId)\n    }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Add Web Markup<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Replace the App Indexing API&#39;s content reporting with web-side markup:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Add <code>&lt;link rel=&quot;alternate&quot;&gt;<\/code> tags to your web pages.<\/li>\n<li>Add structured data with <code>potentialAction<\/code> for richer results.<\/li>\n<li>Submit your sitemap to Search Console with app link annotations.<\/li>\n<\/ol>\n\n\n\n<pre><code class=\"language-html\">&lt;head&gt;\n  &lt;link rel=&quot;alternate&quot; href=&quot;android-app:\/\/com.yourapp.android\/https\/www.yourapp.com\/products\/123&quot; \/&gt;\n&lt;\/head&gt;\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Verify in Search Console<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open <a href=\"https:\/\/search.google.com\/search-console\" rel=\"nofollow noopener\" target=\"_blank\">Google Search Console<\/a>.<\/li>\n<li>Go to Settings &gt; Associations.<\/li>\n<li>Link your Android app.<\/li>\n<li>Use the URL Inspection tool to verify that app link annotations are detected.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Monitor App Search Traffic<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">After migration, monitor your app&#39;s search performance:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Check Search Console for app-specific impressions and clicks.<\/li>\n<li>Compare with your pre-migration baseline.<\/li>\n<li>If app impressions drop, verify that your web markup and <code>assetlinks.json<\/code> are correct.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">What You Lose<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Some Firebase App Indexing features have no direct replacement:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Personal Content Indexing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The App Indexing API could index personal\/private content (messages, notes) that was only searchable on the user&#39;s device. The web markup approach only works for content that has a public web URL.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Alternative:<\/strong> Use <a href=\"https:\/\/developer.apple.com\/documentation\/corespotlight\" rel=\"nofollow noopener\" target=\"_blank\">CoreSpotlight<\/a> on iOS and Android&#39;s <a href=\"https:\/\/developer.android.com\/guide\/topics\/search\" rel=\"nofollow noopener\" target=\"_blank\">on-device search APIs<\/a> for personal content indexing.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Automatic Snippets<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Firebase App Indexing automatically generated search snippets from indexed content. With web markup, you control snippets through your web page&#39;s metadata (title tag, meta description, structured data).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Firebase Console Analytics<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Firebase App Indexing provided analytics in the Firebase Console showing how often your app appeared in search and how many clicks it received. This data now lives in Google Search Console instead.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common Migration Issues<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">&quot;My app stopped appearing in search results&quot;<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Most likely cause: your <code>assetlinks.json<\/code> file is not being served correctly. Verify:<\/p>\n\n\n\n<pre><code class=\"language-bash\">curl -s &quot;https:\/\/digitalassetlinks.googleapis.com\/v1\/statements:list?source.web.site=https:\/\/www.yourapp.com&amp;relation=delegate_permission\/common.handle_all_urls&quot;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If this returns an empty result, your verification file has a problem.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">&quot;Deep links from search open the browser instead of my app&quot;<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Your intent filters may not match the URL pattern, or App Links verification failed. Check:<\/p>\n\n\n\n<pre><code class=\"language-bash\">adb shell pm get-app-links com.yourapp.android\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Look for <code>verified<\/code> status on your domain.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">&quot;My search impressions dropped after migration&quot;<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Give it 2-4 weeks. Google needs to re-crawl your pages and detect the new markup. Submit your sitemap to speed up crawling. If impressions do not recover, check that your alternate link tags and structured data are correctly formatted.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Tolinku as Firebase Replacement<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/tolinku.com\/docs\/migrations\/from-firebase\/\">Tolinku<\/a> provides a migration path from Firebase Dynamic Links that includes the app indexing infrastructure. When you configure your Appspace with your Android app settings, Tolinku hosts the <code>assetlinks.json<\/code> file automatically. Your deep link routes work as both user-facing deep links and search-indexable URLs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the full Firebase migration, see <a href=\"https:\/\/tolinku.com\/blog\/migrate-from-firebase-dynamic-links\/\">Firebase Dynamic Links migration guide<\/a>. For the broader app indexing strategy, see <a href=\"https:\/\/tolinku.com\/blog\/app-indexing-seo-mobile-apps\/\">app indexing and SEO for mobile apps<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Firebase App Indexing was deprecated along with Dynamic Links. Learn what replaced it, how to maintain app search visibility, and how to migrate to modern alternatives.<\/p>\n","protected":false},"author":2,"featured_media":1437,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Firebase App Indexing: What Replaced It and How to Migrate","rank_math_description":"Firebase App Indexing was deprecated along with Dynamic Links. Learn what replaced it and how to maintain app search visibility.","rank_math_focus_keyword":"Firebase App Indexing","rank_math_canonical_url":"","rank_math_facebook_title":"","rank_math_facebook_description":"","rank_math_facebook_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-firebase-app-indexing.png","rank_math_facebook_image_id":"","rank_math_twitter_title":"","rank_math_twitter_description":"","rank_math_twitter_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-firebase-app-indexing.png","footnotes":""},"categories":[16],"tags":[25,64,20,54,354,52,69,63],"class_list":["post-1438","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-marketing","tag-android","tag-app-indexing","tag-deep-linking","tag-firebase","tag-google-search","tag-migration","tag-mobile-development","tag-seo"],"_links":{"self":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1438","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/comments?post=1438"}],"version-history":[{"count":4,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1438\/revisions"}],"predecessor-version":[{"id":2602,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1438\/revisions\/2602"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media\/1437"}],"wp:attachment":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media?parent=1438"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/categories?post=1438"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/tags?post=1438"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}