CINXE.COM

Get started with Game Loop tests for iOS  |  Firebase Test Lab

<!doctype html> <html lang="en" dir="ltr"> <head> <meta name="google-signin-client-id" content="721724668570-nbkv1cfusk7kk4eni4pjvepaus73b13t.apps.googleusercontent.com"> <meta name="google-signin-scope" content="profile email https://www.googleapis.com/auth/developerprofiles https://www.googleapis.com/auth/developerprofiles.award"> <meta property="og:site_name" content="Firebase"> <meta property="og:type" content="website"><meta name="theme-color" content="#a8c7fa"><meta charset="utf-8"> <meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="manifest" href="/_pwa/firebase/manifest.json" crossorigin="use-credentials"> <link rel="preconnect" href="//www.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.googleapis.com" crossorigin> <link rel="preconnect" href="//apis.google.com" crossorigin> <link rel="preconnect" href="//www.google-analytics.com" crossorigin><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"> <link rel="stylesheet" href="//fonts.googleapis.com/css2?family=Material+Icons&family=Material+Symbols+Outlined&display=block"><link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/css/app.css"> <link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/css/dark-theme.css" disabled> <link rel="shortcut icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/favicon.png"> <link rel="apple-touch-icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/touchicon-180.png"><link rel="canonical" href="https://firebase.google.com/docs/test-lab/game-loop"><link rel="search" type="application/opensearchdescription+xml" title="Firebase" href="https://firebase.google.com/s/opensearch.xml"> <link rel="alternate" hreflang="en" href="https://firebase.google.com/docs/test-lab/game-loop" /><link rel="alternate" hreflang="x-default" href="https://firebase.google.com/docs/test-lab/game-loop" /><link rel="alternate" hreflang="ar" href="https://firebase.google.com/docs/test-lab/game-loop?hl=ar" /><link rel="alternate" hreflang="bn" href="https://firebase.google.com/docs/test-lab/game-loop?hl=bn" /><link rel="alternate" hreflang="zh-Hans" href="https://firebase.google.com/docs/test-lab/game-loop?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant" href="https://firebase.google.com/docs/test-lab/game-loop?hl=zh-tw" /><link rel="alternate" hreflang="fa" href="https://firebase.google.com/docs/test-lab/game-loop?hl=fa" /><link rel="alternate" hreflang="fr" href="https://firebase.google.com/docs/test-lab/game-loop?hl=fr" /><link rel="alternate" hreflang="de" href="https://firebase.google.com/docs/test-lab/game-loop?hl=de" /><link rel="alternate" hreflang="he" href="https://firebase.google.com/docs/test-lab/game-loop?hl=he" /><link rel="alternate" hreflang="hi" href="https://firebase.google.com/docs/test-lab/game-loop?hl=hi" /><link rel="alternate" hreflang="id" href="https://firebase.google.com/docs/test-lab/game-loop?hl=id" /><link rel="alternate" hreflang="it" href="https://firebase.google.com/docs/test-lab/game-loop?hl=it" /><link rel="alternate" hreflang="ja" href="https://firebase.google.com/docs/test-lab/game-loop?hl=ja" /><link rel="alternate" hreflang="ko" href="https://firebase.google.com/docs/test-lab/game-loop?hl=ko" /><link rel="alternate" hreflang="pl" href="https://firebase.google.com/docs/test-lab/game-loop?hl=pl" /><link rel="alternate" hreflang="pt-BR" href="https://firebase.google.com/docs/test-lab/game-loop?hl=pt-br" /><link rel="alternate" hreflang="pt" href="https://firebase.google.com/docs/test-lab/game-loop?hl=pt" /><link rel="alternate" hreflang="ru" href="https://firebase.google.com/docs/test-lab/game-loop?hl=ru" /><link rel="alternate" hreflang="es" href="https://firebase.google.com/docs/test-lab/game-loop?hl=es" /><link rel="alternate" hreflang="es-419" href="https://firebase.google.com/docs/test-lab/game-loop?hl=es-419" /><link rel="alternate" hreflang="th" href="https://firebase.google.com/docs/test-lab/game-loop?hl=th" /><link rel="alternate" hreflang="tr" href="https://firebase.google.com/docs/test-lab/game-loop?hl=tr" /><link rel="alternate" hreflang="vi" href="https://firebase.google.com/docs/test-lab/game-loop?hl=vi" /><title>Get started with Game Loop tests for iOS &nbsp;|&nbsp; Firebase Test Lab</title> <meta property="og:title" content="Get started with Game Loop tests for iOS &nbsp;|&nbsp; Firebase Test Lab"><meta property="og:url" content="https://firebase.google.com/docs/test-lab/game-loop"><meta property="og:locale" content="en"><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{ "@type": "ListItem", "position": 1, "name": "Documentation", "item": "https://firebase.google.com/docs" },{ "@type": "ListItem", "position": 2, "name": "Test Lab", "item": "https://firebase.google.com/docs/test-lab" },{ "@type": "ListItem", "position": 3, "name": "Get started with Game Loop tests for iOS", "item": "https://firebase.google.com/docs/test-lab/game-loop" }] } </script> <link rel="stylesheet" href="/extras.css"></head> <body class="" template="page" theme="firebase-icy-theme" type="guide" appearance layout="docs" concierge='closed' display-toc pending> <devsite-progress type="indeterminate" id="app-progress"></devsite-progress> <section class="devsite-wrapper"> <devsite-cookie-notification-bar></devsite-cookie-notification-bar><devsite-header role="banner" keep-tabs-visible> <div class="devsite-header--inner nocontent"> <div class="devsite-top-logo-row-wrapper-wrapper"> <div class="devsite-top-logo-row-wrapper"> <div class="devsite-top-logo-row"> <button type="button" id="devsite-hamburger-menu" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Navigation menu button" visually-hidden aria-label="Open menu"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="firebase" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="Firebase"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup.svg" class="devsite-site-logo" alt="Firebase"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> <div class="devsite-top-logo-row-middle"> <div class="devsite-header-upper-tabs"> <devsite-tabs class="upper-tabs"> <nav class="devsite-tabs-wrapper" aria-label="Upper tabs"> <tab class="devsite-dropdown "> <a href="https://firebase.google.com/products-build" track-metadata-eventdetail="https://firebase.google.com/products-build" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - build" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Build" track-name="build" > Build </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="false" aria-label="Dropdown menu for Build" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products-build" track-metadata-position="nav - build" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Build" track-name="build" class="devsite-tabs-dropdown-toggle devsite-icon devsite-icon-arrow-drop-down"></a> <div class="devsite-tabs-dropdown" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column firebase-dropdown firebase-dropdown--primary firebase-build"> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Build</li> <li class="devsite-nav-description">Get to market quickly and securely with products that can scale globally </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products-build" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products-build" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build" tooltip > <div class="devsite-nav-item-title"> Go to Build </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column firebase-dropdown firebase-dropdown--secondary firebase-build"> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Build Products</li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/app-check" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/app-check" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> App Check </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/app-hosting" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/app-hosting" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> App Hosting </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/auth" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/auth" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Authentication </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/functions" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/functions" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Cloud Functions </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/storage" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/storage" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Cloud Storage </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/data-connect" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/data-connect" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Data Connect </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/extensions" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/extensions" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Extensions </div> </a> </li> </ul> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/ml" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/ml" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Firebase ML </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/firestore" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/firestore" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Firestore </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/genkit" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/genkit" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Genkit </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/hosting" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/hosting" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Hosting </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/realtime-database" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/realtime-database" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Realtime Database </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/vertex-ai-in-firebase" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/vertex-ai-in-firebase" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Vertex AI in Firebase </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/generative-ai" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/generative-ai" track-metadata-position="nav - build" track-metadata-module="tertiary nav" track-metadata-module_headline="build products" tooltip > <div class="devsite-nav-item-title"> Generative AI </div> </a> </li> </ul> </div> </div> </div> </tab> <tab class="devsite-dropdown "> <a href="https://firebase.google.com/products-run" track-metadata-eventdetail="https://firebase.google.com/products-run" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - run" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Run" track-name="run" > Run </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="false" aria-label="Dropdown menu for Run" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products-run" track-metadata-position="nav - run" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Run" track-name="run" class="devsite-tabs-dropdown-toggle devsite-icon devsite-icon-arrow-drop-down"></a> <div class="devsite-tabs-dropdown" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column firebase-dropdown firebase-dropdown--primary firebase-run"> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Run</li> <li class="devsite-nav-description">Run your app with confidence and deliver the best experience for your users </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products-run" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products-run" track-metadata-position="nav - run" track-metadata-module="tertiary nav" track-metadata-module_headline="run" tooltip > <div class="devsite-nav-item-title"> Go to Run </div> </a> </li> </ul> </div> <div class="devsite-tabs-dropdown-column firebase-dropdown firebase-dropdown--secondary"> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-title" role="heading" tooltip>Run Products</li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/ab-testing" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/ab-testing" track-metadata-position="nav - run" track-metadata-module="tertiary nav" track-metadata-module_headline="run products" tooltip > <div class="devsite-nav-item-title"> A/B Testing </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/app-distribution" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/app-distribution" track-metadata-position="nav - run" track-metadata-module="tertiary nav" track-metadata-module_headline="run products" tooltip > <div class="devsite-nav-item-title"> App Distribution </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/cloud-messaging" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/cloud-messaging" track-metadata-position="nav - run" track-metadata-module="tertiary nav" track-metadata-module_headline="run products" tooltip > <div class="devsite-nav-item-title"> Cloud Messaging </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/crashlytics" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/crashlytics" track-metadata-position="nav - run" track-metadata-module="tertiary nav" track-metadata-module_headline="run products" tooltip > <div class="devsite-nav-item-title"> Crashlytics </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/analytics" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/analytics" track-metadata-position="nav - run" track-metadata-module="tertiary nav" track-metadata-module_headline="run products" tooltip > <div class="devsite-nav-item-title"> Google Analytics </div> </a> </li> </ul> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/in-app-messaging" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/in-app-messaging" track-metadata-position="nav - run" track-metadata-module="tertiary nav" track-metadata-module_headline="run products" tooltip > <div class="devsite-nav-item-title"> In-App Messaging </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/performance" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/performance" track-metadata-position="nav - run" track-metadata-module="tertiary nav" track-metadata-module_headline="run products" tooltip > <div class="devsite-nav-item-title"> Performance Monitoring </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/remote-config" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/remote-config" track-metadata-position="nav - run" track-metadata-module="tertiary nav" track-metadata-module_headline="run products" tooltip > <div class="devsite-nav-item-title"> Remote Config </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/products/test-lab" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/products/test-lab" track-metadata-position="nav - run" track-metadata-module="tertiary nav" track-metadata-module_headline="run products" tooltip > <div class="devsite-nav-item-title"> Test Lab </div> </a> </li> </ul> </div> </div> </div> </tab> <tab > <a href="https://firebase.google.com/solutions" track-metadata-eventdetail="https://firebase.google.com/solutions" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - solutions" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Solutions" track-name="solutions" > Solutions </a> </tab> <tab > <a href="https://firebase.google.com/pricing" track-metadata-eventdetail="https://firebase.google.com/pricing" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - pricing" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Pricing" track-name="pricing" > Pricing </a> </tab> <tab class="devsite-dropdown "> <a href="https://firebase.google.com/docs" track-metadata-eventdetail="https://firebase.google.com/docs" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - docs" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" > Docs </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="false" aria-label="Dropdown menu for Docs" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/docs" track-metadata-position="nav - docs" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" class="devsite-tabs-dropdown-toggle devsite-icon devsite-icon-arrow-drop-down"></a> <div class="devsite-tabs-dropdown" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-item"> <a href="https://firebase.google.com/docs" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/docs" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" tooltip > <div class="devsite-nav-item-title"> Overview </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/docs/guides" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/docs/guides" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" tooltip > <div class="devsite-nav-item-title"> Fundamentals </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/docs/build" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/docs/build" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" tooltip > <div class="devsite-nav-item-title"> Build </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/docs/run" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/docs/run" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" tooltip > <div class="devsite-nav-item-title"> Run </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/docs/reference" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/docs/reference" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" tooltip > <div class="devsite-nav-item-title"> Reference </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/docs/samples" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/docs/samples" track-metadata-position="nav - docs" track-metadata-module="tertiary nav" tooltip > <div class="devsite-nav-item-title"> Samples </div> </a> </li> </ul> </div> </div> </div> </tab> <tab class="devsite-dropdown "> <a href="https://firebase.google.com/community" track-metadata-eventdetail="https://firebase.google.com/community" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - community" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Community" track-name="community" > Community </a> <a href="#" role="button" aria-haspopup="true" aria-expanded="false" aria-label="Dropdown menu for Community" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/community" track-metadata-position="nav - community" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Community" track-name="community" class="devsite-tabs-dropdown-toggle devsite-icon devsite-icon-arrow-drop-down"></a> <div class="devsite-tabs-dropdown" aria-label="submenu" hidden> <div class="devsite-tabs-dropdown-content"> <div class="devsite-tabs-dropdown-column "> <ul class="devsite-tabs-dropdown-section "> <li class="devsite-nav-item"> <a href="https://firebase.google.com/community/learn" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/community/learn" track-metadata-position="nav - community" track-metadata-module="tertiary nav" tooltip > <div class="devsite-nav-item-title"> Learn </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/community/events" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/community/events" track-metadata-position="nav - community" track-metadata-module="tertiary nav" tooltip > <div class="devsite-nav-item-title"> Events </div> </a> </li> <li class="devsite-nav-item"> <a href="https://firebase.google.com/community/stories" track-type="nav" track-metadata-eventdetail="https://firebase.google.com/community/stories" track-metadata-position="nav - community" track-metadata-module="tertiary nav" tooltip > <div class="devsite-nav-item-title"> Stories </div> </a> </li> </ul> </div> </div> </div> </tab> <tab > <a href="https://firebase.google.com/support" track-metadata-eventdetail="https://firebase.google.com/support" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - support" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Support" track-name="support" > Support </a> </tab> </nav> </devsite-tabs> </div> <devsite-search enable-signin enable-search enable-suggestions enable-query-completion project-name="Firebase Test Lab" tenant-name="Firebase" > <form class="devsite-search-form" action="https://firebase.google.com/s/results" method="GET"> <div class="devsite-search-container"> <button type="button" search-open class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Open search"></button> <div class="devsite-searchbox"> <input aria-activedescendant="" aria-autocomplete="list" aria-label="Search" aria-expanded="false" aria-haspopup="listbox" autocomplete="off" class="devsite-search-field devsite-search-query" name="q" placeholder="Search" role="combobox" type="text" value="" > <div class="devsite-search-image material-icons" aria-hidden="true"> </div> <div class="devsite-search-shortcut-icon-container" aria-hidden="true"> <kbd class="devsite-search-shortcut-icon">/</kbd> </div> </div> </div> </form> <button type="button" search-close class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Close search"></button> </devsite-search> </div> <devsite-appearance-selector></devsite-appearance-selector> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es" >Español</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt" >Português</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> <a class="devsite-header-link devsite-top-button button gc-analytics-event" href="//console.firebase.google.com" data-category="Site-Wide Custom Events" data-label="Site header link" > Go to console </a> <devsite-user enable-profiles fp-auth id="devsite-user"> <span class="button devsite-top-button" aria-hidden="true" visually-hidden>Sign in</span> </devsite-user> </div> </div> </div> <div class="devsite-collapsible-section devsite-header-no-lower-tabs "> <div class="devsite-header-background"> <div class="devsite-product-id-row" > <div class="devsite-product-description-row"> <ul class="devsite-breadcrumb-list" aria-label="Lower header breadcrumb"> <li class="devsite-breadcrumb-item "> <a href="https://firebase.google.com/docs" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Lower Header" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="Firebase Documentation" > Documentation </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://firebase.google.com/docs/test-lab" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Lower Header" data-value="2" track-type="globalNav" track-name="breadcrumb" track-metadata-position="2" track-metadata-eventdetail="Firebase Test Lab" > Test Lab </a> </li> </ul> </div> </div> </div> </div> </div> </devsite-header> <devsite-book-nav scrollbars hidden> <div class="devsite-book-nav-filter" hidden> <span class="filter-list-icon material-icons" aria-hidden="true"></span> <input type="text" placeholder="Filter" aria-label="Type to filter" role="searchbox"> <span class="filter-clear-button hidden" data-title="Clear filter" aria-label="Clear filter" role="button" tabindex="0"></span> </div> <nav class="devsite-book-nav devsite-nav nocontent" aria-label="Side menu"> <div class="devsite-mobile-header"> <button type="button" id="devsite-close-nav" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Close navigation" aria-label="Close navigation"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="firebase" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="Firebase"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup.svg" class="devsite-site-logo" alt="Firebase"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> </div> <div class="devsite-book-nav-wrapper"> <div class="devsite-mobile-nav-top"> <ul class="devsite-nav-list"> <li class="devsite-nav-item"> <a href="/products-build" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Build" track-name="build" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Build" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Build </span> </a> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Build" track-name="build" > <span class="devsite-nav-text" tooltip menu="Build"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Build"> </span> </span> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/products-run" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Run" track-name="run" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Run" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Run </span> </a> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Run" track-name="run" > <span class="devsite-nav-text" tooltip menu="Run"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Run"> </span> </span> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/solutions" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Solutions" track-name="solutions" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Solutions" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Solutions </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/pricing" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Pricing" track-name="pricing" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Pricing" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Pricing </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Docs" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Docs </span> </a> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Docs" track-name="docs" > <span class="devsite-nav-text" tooltip menu="Docs"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Docs"> </span> </span> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/community" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Community" track-name="community" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Community" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Community </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> <ul class="devsite-nav-responsive-tabs devsite-nav-has-menu "> <li class="devsite-nav-item"> <span class="devsite-nav-title" tooltip data-category="Site-Wide Custom Events" data-label="Tab: Community" track-name="community" > <span class="devsite-nav-text" tooltip menu="Community"> More </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="Community"> </span> </span> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/support" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Support" track-name="support" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Support" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Support </span> </a> </li> <li class="devsite-nav-item"> <a href="//console.firebase.google.com" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Go to console" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Go to console </span> </a> </li> </ul> </div> <div class="devsite-mobile-nav-bottom"> <ul class="devsite-nav-list" menu="Build" aria-label="Side menu" hidden> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Build </span> </span> </li> <li class="devsite-nav-item"> <a href="/products-build" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Go to Build" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Go to Build </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Build Products </span> </span> </li> <li class="devsite-nav-item"> <a href="/products/app-check" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: App Check" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > App Check </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/app-hosting" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: App Hosting" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > App Hosting </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/auth" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Authentication" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Authentication </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/functions" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Cloud Functions" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Cloud Functions </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/storage" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Cloud Storage" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Cloud Storage </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/data-connect" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Data Connect" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Data Connect </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/extensions" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Extensions" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Extensions </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/ml" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Firebase ML" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Firebase ML </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/firestore" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Firestore" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Firestore </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/genkit" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Genkit" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Genkit </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/hosting" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Hosting" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Hosting </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/realtime-database" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Realtime Database" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Realtime Database </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/vertex-ai-in-firebase" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Vertex AI in Firebase" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Vertex AI in Firebase </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/generative-ai" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Generative AI" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Generative AI </span> </a> </li> </ul> <ul class="devsite-nav-list" menu="Run" aria-label="Side menu" hidden> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Run </span> </span> </li> <li class="devsite-nav-item"> <a href="/products-run" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Go to Run" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Go to Run </span> </a> </li> <li class="devsite-nav-item devsite-nav-heading"> <span class="devsite-nav-title" tooltip > <span class="devsite-nav-text" tooltip > Run Products </span> </span> </li> <li class="devsite-nav-item"> <a href="/products/ab-testing" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: A/B Testing" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > A/B Testing </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/app-distribution" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: App Distribution" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > App Distribution </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/cloud-messaging" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Cloud Messaging" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Cloud Messaging </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/crashlytics" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Crashlytics" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Crashlytics </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/analytics" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Google Analytics" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Google Analytics </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/in-app-messaging" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: In-App Messaging" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > In-App Messaging </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/performance" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Performance Monitoring" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Performance Monitoring </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/remote-config" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Remote Config" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Remote Config </span> </a> </li> <li class="devsite-nav-item"> <a href="/products/test-lab" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Test Lab" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Test Lab </span> </a> </li> </ul> <ul class="devsite-nav-list" menu="Docs" aria-label="Side menu" hidden> <li class="devsite-nav-item"> <a href="/docs" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Overview" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Overview </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/guides" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Fundamentals" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Fundamentals </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/build" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Build" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Build </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/run" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Run" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Run </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/reference" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Reference" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Reference </span> </a> </li> <li class="devsite-nav-item"> <a href="/docs/samples" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Samples" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Samples </span> </a> </li> </ul> <ul class="devsite-nav-list" menu="Community" aria-label="Side menu" hidden> <li class="devsite-nav-item"> <a href="/community/learn" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Learn" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Learn </span> </a> </li> <li class="devsite-nav-item"> <a href="/community/events" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Events" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Events </span> </a> </li> <li class="devsite-nav-item"> <a href="/community/stories" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Responsive Tab: Stories" track-type="navMenu" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Stories </span> </a> </li> </ul> </div> </div> </nav> </devsite-book-nav> <section id="gc-wrapper"> <main role="main" class="devsite-main-content" > <devsite-content> <article class="devsite-article"><style> /* Styles inlined from /styles/docs.css */ .center { text-align: center } /* Used in AdMob code examples */ .oldcode { opacity: .40; /* IE 8 */ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)"; filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); /* IE <= 7 */ filter:alpha(opacity=40); } .newcode { font-weight: bold; } /* Device Screenshots */ .deviceshot { max-width: 700px; max-height: 400px; } /* Start Changelog styles */ .badge { position: relative; top: -3px; border-radius: 16px; display: inline-block; width: 110px; height: 32px; line-height: 32px; margin-right: 10px; text-transform: uppercase; font-size: 13px; font-weight: 700; text-align: center; color: var(--tenant-inverted-text-color); } .checklist > ul { padding-left: 125px; } .checklist > ul > li { list-style-type: none; margin-bottom: 22px; } .changelog > ul { padding-left: 0; } .changelog > ul > li { list-style-type: none; margin-bottom: 22px; } .firebase-support-release-page .changelog > ul { list-style-type: none; padding-left: 125px; } .firebase-release-roundup .changelog > ul { list-style-type: disc outside; padding-left: 40px; } .firebase-release-roundup .changelog > ul > li { list-style-type: disc outside; margin-bottom: 12px; } .generic-android::before, .generic-ios::before, .generic-mobile::before, .generic-web::before, .generic-flutter::before, .generic-unity::before, .generic-cpp::before, .generic-all::before, .release-changed::before, .release-deprecated::before, .release-feature::before, .release-fixed::before, .release-important::before, .release-issue::before, .release-removed::before, .release-unchanged::before, .release-android::before, .release-android-bom::before, .release-ios::before, .release-javascript::before, .release-flutter::before, .release-unity::before, .release-cpp::before, .release-admin::before, .release-functions::before, .release-cli::before, .release-rules::before { display: block; float: left; width: 110px; height: 32px; margin-left: -125px; margin-right: 10px; border-radius: 16px; text-transform: uppercase; font-size: 13px; font-weight: 700; text-align: center; color: var(--tenant-inverted-text-color); } .generic-android::before { content: "Android"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #839e2e; } .generic-ios::before { text-transform: none; content: "iOS+"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #003fdd; } .generic-mobile::before { content: "Mobile"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #f4b400; } .generic-web::before { content: "Web"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #7e57c2; } .generic-flutter::before { content: "Flutter"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #29b6f6; } .generic-unity::before { content: "Unity"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #7f6545; } .generic-cpp::before { content: "C++"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #ff8c00; } .generic-all::before { content: "All"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #ccc; } .release-changed::before { content: "changed"; background-color: #ff6961; padding-top: 4px; } .release-deprecated::before { content: "deprecated"; background-color: #d70015; padding-top: 4px; } .release-feature::before { content: "feature"; background-color: #0f9d58; padding-top: 4px; } .release-fixed::before { content: "fixed"; background-color: #4285f4; padding-top: 4px; } .release-important::before { content: "important"; background-color: #d70015; padding-top: 4px; } .release-issue::before { content: "issue"; background-color: #d70015; padding-top: 4px; } .release-removed::before { content: "removed"; background-color: #546e7a; padding-top: 4px; } .release-unchanged::before { content: "no change"; background-color: #ccc; padding-top: 4px; } .release-android::before { content: "Android"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #839e2e; } .release-android-bom::before { content: "Android BoM"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #839e2e; } .release-ios::before { text-transform: none; content: "iOS+"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #003fdd; } .release-javascript::before { content: "JavaScript"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #7e57c2; } .release-flutter::before { content: "Flutter"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #29b6f6; } .release-unity::before { content: "Unity"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #7f6545; } .release-cpp::before { content: "C++"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #ff8c00; } .release-admin::before { content: "Admin"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #909090; } .release-functions::before { content: "Functions"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #2c384a; } .release-cli::before { text-transform: none; content: "CLI"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #f4b400; } .release-rules::before { content: "Rules"; color: var(--tenant-secondary-text-color); border: 5px solid; border-color: #002991; } /* End Changelog styles */ /* Docs Overview page styles */ .docs-android, .docs-ios, .docs-web, .docs-cpp, .docs-unity { height: 64px; width: 64px; margin: 10px 16px 0 -16px; } .firebase-docs-overview .devsite-landing-row h2 { margin: 80px 0 -40px; } .devsite-landing-row-3-up .docs-landing-row-item { width: calc((100% - 80px)/2); display: inline-block; } .docs-landing-icon { font-size: 48px; height: 48px; margin: 11px; width: 48px; } .firebase-reference-list { display: -ms-flex; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; list-style: none; margin: 0 0 40px; padding: 0; } .firebase-reference-list-item { -ms-flex: 0 0 50%; flex: 0 0 50%; margin: 40px 0 0; padding: 0; } .firebase-reference-list-item > a { -ms-flex-align: center; align-items: center; display: -ms-flex; display: flex; } .firebase-reference-list-item > a:not(:hover) h3 { color: var(--tenant-primary-text-color); } .firebase-reference-list-item > a:not(:hover) li, .firebase-reference-list-item > a:not(:hover) p { color: var(--tenant-secondary-text-color); } .firebase-reference-list-item .docs-landing-icon { -ms-flex-align: center; align-items: center; background-color: var(--tenant-docs-landing-icon-background, #f5f5f5); border-radius: 50%; -ms-flex: 0 0 88px; flex: 0 0 88px; height: 88px; -ms-justify-content: center; justify-content: center; margin: 0 16px 0 0; padding: 20px; } .firebase-reference-list-item h3 { -ms-flex: 0 0 auto; flex: 0 0 auto; font-size: 18px; line-height: 28px; margin: 0; } .firebase-reference-list-item ul { list-style: none; padding: 0; } .docs-android, .docs-ios, .docs-web, .docs-cpp, .docs-unity { height: 88px; width: auto; } .firebase-reference-list-item.docs-android .docs-landing-icon { color: #00bfa5; } .firebase-reference-list-item.docs-cpp .docs-landing-icon { color: #fd8c09; } .firebase-reference-list-item.docs-ios .docs-landing-icon { color: #16aaca; } .firebase-reference-list-item.docs-unity .docs-landing-icon { color: #000; } .firebase-reference-list-item.docs-web .docs-landing-icon { color: #c52062; } .firebase-reference-list-item.docs-http .docs-landing-icon { color: #3f51b5; } @media (max-width: 1000px) { .firebase-reference-list { -ms-flex-direction: column; flex-direction: column; } } /* end Docs Overview page styles */ /* Full-page platform selector for Crashlytics docs */ /* Note: h3 in selector content must include hide-from-toc */ .full-page-selector, .full-page-selector-content { border: none; font-size: inherit; } .full-page-selector > .kd-buttonbar { margin: 32px 0; } .full-page-selector > section { display: none; } .full-page-selector-content > .selected { padding: 0; font-size: inherit; } .full-page-selector-content > .kd-buttonbar { display: none; } .select-page { display: none; } .select-page + .ds-selector-tabs, .after-selection ~ .ds-selector-tabs { border: none; font-size: inherit; } .select-page + .ds-selector-tabs > .kd-buttonbar { margin: 32px 0; } .select-page + .ds-selector-tabs > section { display: none; } .after-selection ~ .ds-selector-tabs > .selected { padding: 0; font-size: inherit; } .after-selection ~ .ds-selector-tabs > section p { line-height: 24px; } .after-selection ~ .ds-selector-tabs > .kd-buttonbar { display: none; } /* End full-page platform selector */ /* Custom beta and alpha indicators */ .devsite-nav-icon[data-icon="alpha"]::before { content: url(data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'><path d='M13.2,15c-0.3-0.9-0.6-1.7-0.9-2.6L12.1,12c0-0.1-0.1-0.3-0.1-0.4c-1.2,2.1-2.4,2.9-4.5,2.9C4.8,14.5,3,12.6,3,9s1.8-5.5,4.5-5.5c2.1,0,3.4,0.8,4.5,2.9L12.1,6l0.1-0.4c0.4-1.1,0.7-1.9,0.9-2.6h2.2c-0.4,0.8-0.7,1.7-1.2,3.2L14,6.6c-0.3,0.8-0.5,1.6-0.8,2.4c0.3,0.7,0.6,1.5,0.8,2.4l0.1,0.4c0.5,1.5,0.8,2.4,1.2,3.2C15.4,15,13.2,15,13.2,15z M7.5,5.5C5.9,5.5,5,6.5,5,9s0.9,3.5,2.5,3.5C9,12.5,9.9,11.6,11,9C9.9,6.4,9,5.5,7.5,5.5z' fill='%2354617d'/></svg>); } .color-scheme--dark .devsite-nav-icon[data-icon="alpha"]::before { content: url(data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'><path d='M13.2,15c-0.3-0.9-0.6-1.7-0.9-2.6L12.1,12c0-0.1-0.1-0.3-0.1-0.4c-1.2,2.1-2.4,2.9-4.5,2.9C4.8,14.5,3,12.6,3,9s1.8-5.5,4.5-5.5c2.1,0,3.4,0.8,4.5,2.9L12.1,6l0.1-0.4c0.4-1.1,0.7-1.9,0.9-2.6h2.2c-0.4,0.8-0.7,1.7-1.2,3.2L14,6.6c-0.3,0.8-0.5,1.6-0.8,2.4c0.3,0.7,0.6,1.5,0.8,2.4l0.1,0.4c0.5,1.5,0.8,2.4,1.2,3.2C15.4,15,13.2,15,13.2,15z M7.5,5.5C5.9,5.5,5,6.5,5,9s0.9,3.5,2.5,3.5C9,12.5,9.9,11.6,11,9C9.9,6.4,9,5.5,7.5,5.5z' fill='%239eabc3'/></svg>); } .devsite-nav-icon[data-icon="beta"]::before { content: url(data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'><path d='M12.2,7.7c1.8,1.2,2.3,3.7,1.1,5.6c-0.7,1.1-2,1.8-3.3,1.8H7v2H5V4c0-1.1,0.9-2,2-2h2.5C11.4,2,13,3.6,13,5.5C13,6.3,12.7,7.1,12.2,7.7z M7,13h3c1.1,0,2-0.9,2-2s-0.9-2-2-2H7V13z M7,7h2.5C10.3,7,11,6.3,11,5.5S10.3,4,9.5,4H7V7z' fill='%2354617d'/></svg>); } .color-scheme--dark .devsite-nav-icon[data-icon="beta"]::before { content: url(data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'><path d='M12.2,7.7c1.8,1.2,2.3,3.7,1.1,5.6c-0.7,1.1-2,1.8-3.3,1.8H7v2H5V4c0-1.1,0.9-2,2-2h2.5C11.4,2,13,3.6,13,5.5C13,6.3,12.7,7.1,12.2,7.7z M7,13h3c1.1,0,2-0.9,2-2s-0.9-2-2-2H7V13z M7,7h2.5C10.3,7,11,6.3,11,5.5S10.3,4,9.5,4H7V7z' fill='%239eabc3'/></svg>); } .firebase-platform-label { font: 500 12px/24px Roboto,sans-serif; } /* Full-page platform selector dropdown */ /* Note: use menu variables in _elements.html file */ .full-page-selector-dropdown { border: none; position: relative; float: left; display: inline-block; } .full-page-selector-dropdown > .ds-selector-tabs { display: none; position: absolute; min-width: 160px; z-index: 1; } .full-page-selector-dropdown:hover .ds-selector-tabs { display: block; margin: 0; } .full-page-selector-dropdown:hover .kd-tabbutton { display: block; border: none; height: inherit; text-align: left; } .full-page-selector-dropdown:hover .kd-buttonbar { border: none; height: inherit; } .full-page-selector-dropdown h3:hover { color: var(--tenant-inverted-text-color); background-color: #039be5; } .full-page-selector-dropdown:hover .devsite-overflow-menu-button { display: none; } img.white-bg { padding: 5px; border-radius: 2px; background-color: #fff; } </style> <div class="devsite-banner devsite-banner-announcement nocontent" > <div class="devsite-banner-message"> <div class="devsite-banner-message-text"> <style> .devsite-banner-announcement a:link:not(.button), .devsite-banner-announcement a:visited:not(.button) { background: 0; } .devsite-banner-announcement a:hover, .devsite-banner-announcement a:focus { text-decoration: none; } .devsite-banner-announcement .devsite-banner-message-text { margin: 0 auto; } </style> Watch demos on how to build & run AI-powered apps with Firebase at Demo Day '24. <a href="https://firebase.google.com/demo-day/2024?utm_source=firesite&utm_medium=referral&utm_campaign=day_of_firesite_banner&utm_content=" target="_blank" rel="noreferrer noopener">Watch now.</a> </div> </div> </div> <div class="devsite-article-meta nocontent" role="navigation"> <ul class="devsite-breadcrumb-list" aria-label="Breadcrumb"> <li class="devsite-breadcrumb-item "> <a href="https://firebase.google.com/" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="Firebase" > Firebase </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://firebase.google.com/docs" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="2" track-type="globalNav" track-name="breadcrumb" track-metadata-position="2" track-metadata-eventdetail="Firebase Documentation" > Documentation </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://firebase.google.com/docs/test-lab" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="3" track-type="globalNav" track-name="breadcrumb" track-metadata-position="3" track-metadata-eventdetail="Firebase Test Lab" > Test Lab </a> </li> </ul> <devsite-thumb-rating position="header"> </devsite-thumb-rating> </div> <devsite-feedback position="header" project-name="Firebase Test Lab" product-id="719752" bucket="" context="" version="t-devsite-webserver-20241114-r00-rc02.464922260396498922" data-label="Send Feedback Button" track-type="feedback" track-name="sendFeedbackLink" track-metadata-position="header" class="nocontent" project-feedback-url="https://firebase.google.com/support/troubleshooter/report" project-icon="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/touchicon-180.png" project-support-url="https://firebase.google.com/support/" > <button> Send feedback </button> </devsite-feedback> <h1 class="devsite-page-title" tabindex="-1"> Get started with Game Loop tests for iOS </h1> <devsite-feature-tooltip ack-key="AckCollectionsBookmarkTooltipDismiss" analytics-category="Site-Wide Custom Events" analytics-action-show="Callout Profile displayed" analytics-action-close="Callout Profile dismissed" analytics-label="Create Collection Callout" class="devsite-page-bookmark-tooltip nocontent" dismiss-button="true" id="devsite-collections-dropdown" dismiss-button-text="Dismiss" close-button-text="Got it"> <devsite-bookmark></devsite-bookmark> <span slot="popout-heading"> Stay organized with collections </span> <span slot="popout-contents"> Save and categorize content based on your preferences. </span> </devsite-feature-tooltip> <div class="devsite-page-title-meta"><devsite-view-release-notes></devsite-view-release-notes></div> <devsite-toc class="devsite-nav" depth="2" devsite-toc-embedded > </devsite-toc> <div class="devsite-article-body clearfix "> <p></p> <p>With Game Loop tests, you can write tests native to your game engine and then run them in <span class="notranslate">Test Lab</span> on devices you choose. This way, you don&#39;t need to worry about writing for different UI or testing frameworks. A Game Loop test simulates the actions of a real player, and when you run it on <span class="notranslate">Test Lab</span>, it provides a fast and scalable way to verify that your game performs well for your users.</p> <p>This page shows you how to run a Game Loop test, then view and manage your test results in the <span class="notranslate">Test Lab</span> page of the <span class="notranslate">Firebase</span> console. You can also further customize your tests with optional features, such as <a href="#write-results">writing custom test results</a> or <a href="#end-early">ending your test early</a>.</p> <aside class="note"><strong>Note:</strong><span> You can use <span class="notranslate">Test Lab</span> at no charge with the Spark pricing plan, which comes with a limited daily quota. For more information about other pricing plans and usage limits, see <a href="/pricing">Firebase Pricing Plans</a>.</span></aside> <h2 id="what-is-game-loop-test" data-text="What is a Game Loop Test?" tabindex="-1">What is a Game Loop Test?</h2> <p>A loop is a full or partial run-through of your test on your gaming app. You can run a Game Loop test locally on a simulator or on a set of devices in <span class="notranslate">Test Lab</span>. Game Loop tests can be used to:</p> <ul> <li><p>Run through your game as an end user would play it. You can either script the input of the user, let the user be idle, or replace the user with an AI (for example, if you implemented AI in a car racing game, you can put an AI driver in charge of the user’s input).</p></li> <li><p>Run your game at the highest quality setting to find out which devices can support it.</p></li> <li><p>Run a technical test, such as compiling multiple shaders, executing them, and checking that the output is as expected.</p></li> </ul> <h2 id="register-url" data-text="Step 1: Register Test Lab’s custom URL scheme" tabindex="-1">Step 1: Register <span class="notranslate">Test Lab</span>’s custom URL scheme</h2> <p>First, you must register <span class="notranslate">Firebase Test Lab</span>&#39;s custom URL scheme in your app:</p> <ol> <li><p>In Xcode, select a project target.</p></li> <li><p>Click the <strong>Info</strong> tab, then add a new <strong>URL type</strong>.</p></li> <li><p>In the <strong>URL Schemes</strong> field, enter <code translate="no" dir="ltr">firebase-game-loop</code>. You can also register the custom URL scheme by adding it to your project’s <code translate="no" dir="ltr">Info.plist</code> configuration file anywhere within the <code translate="no" dir="ltr">&lt;dict&gt;</code> tag:</p> <pre class="prettyprint" translate="no" dir="ltr"><code translate="no" dir="ltr">&lt;key&gt;CFBundleURLTypes&lt;/key&gt; &lt;array&gt; &lt;dict&gt; &lt;key&gt;CFBundleURLName&lt;/key&gt; &lt;string&gt;&lt;/string&gt; &lt;key&gt;CFBundleTypeRole&lt;/key&gt; &lt;string&gt;Editor&lt;/string&gt; &lt;key&gt;CFBundleURLSchemes&lt;/key&gt; &lt;array&gt; &lt;string&gt;firebase-game-loop&lt;/string&gt; &lt;/array&gt; &lt;/dict&gt; &lt;/array&gt; </code></pre></li> </ol> <p>Your app is now configured to run a test using <span class="notranslate">Test Lab</span>.</p> <h2 id="multi-loops" data-text="Step 2 (optional): Configure your app to run multiple loops" tabindex="-1">Step 2 (optional): Configure your app to run multiple loops</h2> <p>If your app has multiple custom URL schemes registered and you plan to run multiple loops (aka scenarios) in your test, you must specify which loops you want to run in your app at launch time.</p> <p>In your app delegate, override the <code translate="no" dir="ltr">application(_:open:options:)</code> method:</p> <div class="ds-selector-tabs" data-ds-scope="code-sample"> <section><h3 id="swift" data-text="Swift" tabindex="-1">Swift</h3><pre class="prettyprint lang-swift" translate="no" dir="ltr"><code translate="no" dir="ltr">func application(_app: UIApplication, open url: URL options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -&gt; Bool { let components = URLComponents(url: url, resolvingAgainstBaseURL: true)! if components.scheme == &#34;firebase-game-loop&#34; { // ...Enter Game Loop Test logic to override application(_:open:options:). } return true } </code></pre></section> <section><h3 id="objective-c" data-text="Objective-C" tabindex="-1">Objective-C</h3><pre class="prettyprint lang-objc" translate="no" dir="ltr"><code translate="no" dir="ltr">- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary &amp;lt;UIApplicationOpenURLOptionsKey, id&amp;gt; *)options { if ([url.scheme isEqualToString:(@&#34;firebase-game-loop&#34;)]) { // ...Enter Game Loop Test logic to override application(_:open:options:). } } </code></pre></section> </div> <p>When you run multiple loops in your test, the current loop is passed as a parameter to the URL used to launch the app. You can also obtain the current loop number by parsing the <code translate="no" dir="ltr">URLComponents</code> object used to fetch the custom URL scheme:</p> <div class="ds-selector-tabs" data-ds-scope="code-sample"> <section><h3 id="swift_1" data-text="Swift" tabindex="-1">Swift</h3><pre class="prettyprint lang-swift" translate="no" dir="ltr"><code translate="no" dir="ltr">if components.scheme == &#34;firebase-game-loop&#34; { // Iterate over all parameters and find the one with the key &#34;scenario&#34;. let scenarioNum = Int(components.queryItems!.first(where: { $0.name == &#34;scenario&#34; })!.value!)! // ...Write logic specific to the current loop (scenarioNum). } </code></pre></section> <section><h3 id="objective-c_1" data-text="Objective-C" tabindex="-1">Objective-C</h3><pre class="prettyprint lang-objc" translate="no" dir="ltr"><code translate="no" dir="ltr">if ([url.scheme isEqualToString:(@&#34;firebase-game-loop&#34;)]) { // Launch the app as part of a game loop. NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES]; for (NSURLQueryItem *item in [components queryItems]) { if ([item.name isEqualToString:@&#34;scenario&#34;]) { NSInteger scenarioNum = [item.value integerValue]; // ...Write logic specific to the current loop (scenarioNum). } } } </code></pre></section> </div> <h2 id="create-run-test" data-text="Step 3: Create and run a test" tabindex="-1">Step 3: Create and run a test</h2> <p>After you register <span class="notranslate">Test Lab</span>&#39;s custom URL scheme, you can run your test in the <a href="#run-console"><span class="notranslate">Firebase</span> console</a> or with the <a href="#run-gcloud">gcloud beta CLI</a>. If you haven&#39;t already, generate an IPA file for your app (you&#39;ll need to locate it later).</p> <aside class="note"><b>Tip:</b> Before using <span class="notranslate">Test Lab</span>, you can first make sure your game loops work as intended by running your test <a href="#run-local">locally on a simulator.</a></aside> <section class="expandable"> <h4 class="showalways" id="generate-an-ipa-for-your-app" data-text="Generate an IPA for your app" tabindex="-1">Generate an IPA for your app</h4> <p> <ol> <li> In Xcode, select a provisioning profile for the target app. <aside class="note"><strong>Note</strong>: <span class="notranslate">Test Lab</span> re-signs your app with its own provisioning profile and certificate.</aside> </li> <li> From the drop-down menu that appears, click <b>Product > Archive</b>. Select the most recent archive, then click <b>Distribute App</b>. </li> <li> In the window that appears, click <b>Development > Next</b>. </li> <li> <i>Optional:</i> To get a faster build, deselect the <b>Rebuild from Bitcode</b> option, then click <b>Next</b>. <span class="notranslate">Test Lab</span> doesn’t require thinning or rebuilding your app to run a test so you can safely disable this option. </li> <li> Click <b>Export</b>, then enter a directory in which you want to download your app’s IPA file. </li> </ol> </section> <h3 id="run-console" data-text="Run a test in the Firebase console" tabindex="-1">Run a test in the <span class="notranslate">Firebase</span> console</h3> <ol> <li><p>If you haven&#39;t already, open the <a href="https://console.firebase.google.com/"><span class="notranslate">Firebase</span> console</a> and create a project.</p></li> <li><p>On the <span class="notranslate">Test Lab</span> page of the <span class="notranslate">Firebase</span> console, click <strong>Run Your First Test &gt; Run an iOS Game Loop</strong>.</p></li> <li><p>In the <strong>Upload App</strong> section, click <strong>Browse</strong>, then select your app&#39;s IPA file (if you haven’t already, <a href="/docs/test-lab/ios/run-game-loop-test#package-app">generate an IPA file</a> for your app).</p></li> <li><p><em>Optional</em>: If you want to run multiple loops (aka scenarios) at a time or select specific loops to run, enter the loop numbers in the <strong>Scenarios</strong> field.</p> <p>For example, when you enter &quot;1-3, 5&quot;, <span class="notranslate">Test Lab</span> runs loops 1, 2, 3, and 5. By default (if you don&#39;t enter anything in the <strong>Scenarios</strong> field), <span class="notranslate">Test Lab</span> only runs loop 1.</p></li> <li><p>In the <strong>Devices</strong> section, select one or more physical devices you want to test your app on, then click <strong>Start Tests</strong>.</p></li> </ol> <h3 id="run-gcloud" data-text="Run a test with the gcloud beta CLI" tabindex="-1">Run a test with the gcloud beta CLI</h3> <aside style="clear: both;"><b>Note:</b> The gcloud beta CLI command for iOS Game Loop tests is a <b>beta release</b>. This means that the functionality might change in backward-incompatible ways. A beta release is not subject to any SLA or deprecation policy and may receive limited or no support.</aside> <ol> <li><p>If you haven&#39;t already, configure your local gcloud SDK environment, then make sure to install the <a href="https://cloud.google.com/sdk/docs/components#alpha_and_beta_components" class="external">gcloud beta component</a>.</p></li> <li><p>Run the <code translate="no" dir="ltr">gcloud beta firebase test ios run</code> command and use the following flags to configure the run:</p></li> </ol> <table class="responsive"> <thead> <tr> <th colspan=2>Flags for Game Loop tests</th> </tr> </thead> <tbody> <tr> <td> <code translate="no" dir="ltr">--type</code> </td> <td> <p><b>Required</b>: Specifies the type of iOS test you want to run. You can enter test types <code translate="no" dir="ltr">xctest</code> (default) or <code translate="no" dir="ltr">game-loop</code>.</p> </td> </tr> <tr> <td> <code translate="no" dir="ltr">--app</code> </td> <td> <p><b>Required</b>: Absolute path (<span class="notranslate">Google Cloud Storage</span> or filesystem) to your app’s IPA file. This flag is only valid when running Game Loop tests. </p> </td> </tr> <tr> <td> <code translate="no" dir="ltr">--scenario-numbers</code> </td> <td> <p> The loops (aka scenarios) you want to run in your app. You can enter one loop, a list or loops, or a range of loops. The default loop is 1. </p> <p> For example, <code translate="no" dir="ltr">--scenario-numbers=1-3,5</code> runs loops 1, 2, 3, and 5. </p> </td> </tr> <tr> <td> <code translate="no" dir="ltr">--device-model</code> </td> <td> <p> The physical device you want to run your test on (find out which <a href="/docs/test-lab/ios/available-testing-devices">available devices</a> you can use). </p> </td> </tr> <tr> <td> <code translate="no" dir="ltr">--timeout</code> </td> <td> <p>The maximum duration you want your test to run. You can enter an integer to represent the duration in seconds, or an integer and enumeration to represent the duration as a longer unit of time.</p> <p>For example: </p> <ul> <li> <code translate="no" dir="ltr">--timeout=200</code> forces your test to terminate when it runs up to 200 seconds. </li> <li> <code translate="no" dir="ltr">--timeout=1h</code> forces your test to terminate when it runs up to an hour. </li> </ul> </td> </tr> </tbody> </table> <p>For example, the following command runs a Game Loop test that executes loops 1, 4, 6, 7, and 8 on an iPhone 8 Plus:</p> <pre class="devsite-terminal devsite-click-to-copy" translate="no" dir="ltr">gcloud beta firebase test ios run --type game-loop --app path/to/my/App.ipa --scenario-numbers 1,4,6-8 --device-model=iphone8plus </pre> <p>For more information on the gcloud CLI, see the <a href="https://cloud.google.com/sdk/gcloud/reference/beta/" class="external">reference documentation</a>.</p> <h3 id="run-local" data-text="Run a test locally" tabindex="-1">Run a test locally</h3> <p>To run your test locally, load your gaming app in a simulator and run:</p> <pre class="devsite-terminal devsite-click-to-copy" translate="no" dir="ltr"> xcrun simctl openurl <var translate="no">SIMULATOR_UDID</var> firebase-game-loop:// </pre> <ul> <li><p>You can find your simulator&#39;s UDID by running the <code translate="no" dir="ltr">instruments -s devices</code> command.</p></li> <li><p>If there is only one simulator running, enter the special string <code translate="no" dir="ltr">&quot;booted&quot;</code> in place of <var translate="no">SIMULATOR_UDID</var>.</p></li> </ul> <p>If your test contains multiple loops, you can specify which loop you want to run by passing the loop number to the <code translate="no" dir="ltr">scenario</code> flag. Note that you can only run one loop at a time when running your test locally. For example, if you want to run loops 1, 2, and 5, you must run a separate command for each loop:</p> <pre class="prettyprint" translate="no" dir="ltr"> <code class="devsite-terminal" translate="no" dir="ltr">xcrun simctl openurl <var translate="no">SIMULATOR_UDID</var> firebase-game-loop://?scenario=1</code> <code class="devsite-terminal" translate="no" dir="ltr">xcrun simctl openurl <var translate="no">SIMULATOR_UDID</var> firebase-game-loop://?scenario=2</code> <code class="devsite-terminal" translate="no" dir="ltr">xcrun simctl openurl <var translate="no">SIMULATOR_UDID</var> firebase-game-loop://?scenario=5</code> </pre> <h2 id="end-early" data-text="End a test early" tabindex="-1">End a test early</h2> <p>By default, a Game Loop test continues running until it reaches a timeout of five minutes, even when all the loops have been executed. When the timeout is reached, the test ends and cancels any pending loops. You can speed up your test or end it early by calling <span class="notranslate">Test Lab</span>’s custom URL scheme <code translate="no" dir="ltr">firebase-game-loop-complete</code> in your app’s AppDelegate. For example:</p> <div class="ds-selector-tabs" data-ds-scope="code-sample"> <section><h3 id="swift_2" data-text="Swift" tabindex="-1">Swift</h3><pre class="prettyprint lang-swift" translate="no" dir="ltr"><code translate="no" dir="ltr">/// End the loop by calling our custom url scheme. func finishLoop() { let url = URL(string: &#34;firebase-game-loop-complete://&#34;)! UIApplication.shared.open(url) } </code></pre></section> <section><h3 id="objective-c_2" data-text="Objective-C" tabindex="-1">Objective-C</h3><pre class="prettyprint lang-objc" translate="no" dir="ltr"><code translate="no" dir="ltr">- (void)finishLoop { UIApplication *app = [UIApplication sharedApplication]; [app openURL:[NSURL URLWithString:@&#34;firebase-game-loop-complete://&#34;] options:@{} completionHandler:^(BOOL success) {}]; } </code></pre></section> </div> <p>Your Game Loop test terminates the current loop and executes the next loop. When there are no more loops to run, the test ends.</p> <h2 id="write-results" data-text="Write custom test results" tabindex="-1">Write custom test results</h2> <p>You can configure your Game Loop test to write custom test results to your device’s file system. This way, when the test starts running, <span class="notranslate">Test Lab</span> stores the result files in a <code translate="no" dir="ltr">GameLoopsResults</code> directory on your testing device (which you must create yourself). When the test ends, <span class="notranslate">Test Lab</span> moves all files from the <code translate="no" dir="ltr">GameLoopResults</code> directory to your project&#39;s bucket. Keep the following in mind when setting up your test:</p> <ul> <li><p>All result files are uploaded regardless of file type, size, or quantity.</p></li> <li><p><span class="notranslate">Test Lab</span> doesn’t process your test results until all the loops in your test have finished running, so if your test includes multiple loops that write output, make sure you append them to a unique result file or create a result file for each loop. This way, you can avoid overwriting results from a previous loop.</p></li> </ul> <p>To set up your test to write custom test results:</p> <ol> <li><p>In your app&#39;s <code translate="no" dir="ltr">Documents</code> directory, create a directory named <code translate="no" dir="ltr">GameLoopResults</code>.</p></li> <li><p>From anywhere in your app’s code (e.g., your app delegate), add the following:</p> <div class="ds-selector-tabs" data-ds-scope="code-sample"> <section><h3 id="swift_3" data-text="Swift" tabindex="-1">Swift</h3><pre class="prettyprint lang-swift" translate="no" dir="ltr"><code translate="no" dir="ltr">/// Write to a results file. func writeResults() { let text = &#34;Greetings from game loops!&#34; let fileName = &#34;results.txt&#34; let fileManager = FileManager.default do { let docs = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) let resultsDir = docs.appendingPathComponent(&#34;GameLoopResults&#34;) try fileManager.createDirectory( at: resultsDir, withIntermediateDirectories: true, attributes: nil) let fileURL = resultsDir.appendingPathComponent(fileName) try text.write(to: fileURL, atomically: false, encoding: .utf8) } catch { // ...Handle error writing to file. } } </code></pre></section> <section><h3 id="objective-c_3" data-text="Objective-C" tabindex="-1">Objective-C</h3><pre class="prettyprint lang-objc" translate="no" dir="ltr"><code translate="no" dir="ltr">/// Write to a results file. - (void)writeResults:(NSString *)message { // Locate and create the results directory (if it doesn&#39;t exist already). NSFileManager *manager = [NSFileManager defaultManager]; NSURL* url = [[manager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; NSURL* resultsDir = [url URLByAppendingPathComponent:@&#34;GameLoopResults&#34; isDirectory:YES]; [manager createDirectoryAtURL:resultsDir withIntermediateDirectories:NO attributes:nil error:nil]; // Write the result message to a text file. NSURL* resultFile = [resultsDir URLByAppendingPathComponent:@&#34;result.txt&#34;]; if ([manager fileExistsAtPath:[resultFile path]]) { // Append to the existing file NSFileHandle *handle = [NSFileHandle fileHandleForWritingToURL:resultFile error:nil]; [handle seekToEndOfFile]; [handle writeData:[message dataUsingEncoding:NSUTF8StringEncoding]]; [handle closeFile]; } else { // Create and write to the file. [message writeToURL:resultFile atomically:NO encoding:NSUTF8StringEncoding error:nil]; } } </code></pre></section> </div></li> </ol> <devsite-hats-survey class="nocontent" hats-id="Eo9GZTcG10ncf3CThQj0SEgFWynR" listnr-id="5244646"></devsite-hats-survey> </div> <devsite-thumb-rating position="footer"> </devsite-thumb-rating> <devsite-feedback position="footer" project-name="Firebase Test Lab" product-id="719752" bucket="" context="" version="t-devsite-webserver-20241114-r00-rc02.464922260396498922" data-label="Send Feedback Button" track-type="feedback" track-name="sendFeedbackLink" track-metadata-position="footer" class="nocontent" project-feedback-url="https://firebase.google.com/support/troubleshooter/report" project-icon="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/touchicon-180.png" project-support-url="https://firebase.google.com/support/" > <button> Send feedback </button> </devsite-feedback> <div class="devsite-floating-action-buttons"> </div> </article> <devsite-content-footer class="nocontent"> <p>Except as otherwise noted, the content of this page is licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 License</a>, and code samples are licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>. For details, see the <a href="https://developers.google.com/site-policies">Google Developers Site Policies</a>. Java is a registered trademark of Oracle and/or its affiliates.</p> <p>Last updated 2024-11-21 UTC.</p> </devsite-content-footer> <devsite-notification > </devsite-notification> <div class="devsite-content-data"> <template class="devsite-thumb-rating-feedback"> <devsite-feedback position="thumb-rating" project-name="Firebase Test Lab" product-id="719752" bucket="" context="" version="t-devsite-webserver-20241114-r00-rc02.464922260396498922" data-label="Send Feedback Button" track-type="feedback" track-name="sendFeedbackLink" track-metadata-position="thumb-rating" class="nocontent" project-feedback-url="https://firebase.google.com/support/troubleshooter/report" project-icon="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/touchicon-180.png" project-support-url="https://firebase.google.com/support/" > <button> Need to tell us more? </button> </devsite-feedback> </template> <template class="devsite-content-data-template"> [[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-11-21 UTC."],[],[]] </template> </div> </devsite-content> </main> <devsite-footer-promos class="devsite-footer"> </devsite-footer-promos> <devsite-footer-linkboxes class="devsite-footer"> <nav class="devsite-footer-linkboxes nocontent" aria-label="Footer links"> <ul class="devsite-footer-linkboxes-list"> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Learn</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="/docs/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Developer guides </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/docs/reference/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > SDK & API reference </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/docs/samples/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Samples </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/docs/libraries/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Libraries </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//github.com/firebase/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > GitHub </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Stay connected</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="//firebase.blog" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Check out the blog </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//www.reddit.com/r/Firebase" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Find us on Reddit </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//x.com/Firebase" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Follow on X </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//www.youtube.com/user/Firebase" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Subscribe on YouTube </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/community/events" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > Attend an event </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Support</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="/support/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Contact support </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//stackoverflow.com/questions/tagged/firebase" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Stack Overflow </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//firebase.community/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Slack community </a> </li> <li class="devsite-footer-linkbox-item"> <a href="//groups.google.com/forum/#!forum/firebase-talk" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Google group </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/support/releases" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 5)" > Release notes </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/brand-guidelines/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 6)" > Brand guidelines </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/support/faq/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 7)" > FAQs </a> </li> </ul> </li> </ul> </nav> </devsite-footer-linkboxes> <devsite-footer-utility class="devsite-footer"> <div class="devsite-footer-utility nocontent"> <nav class="devsite-footer-sites" aria-label="Other Google Developers websites"> <a href="https://developers.google.com/" class="devsite-footer-sites-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Google Developers Link"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup-google-for-developers-dark-theme.svg" media="(prefers-color-scheme: none)" class="devsite-dark-theme" loading="lazy" alt="Google Developers"> <img class="devsite-footer-sites-logo" src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup-google-for-developers.svg" loading="lazy" alt="Google Developers"> </picture> </a> <ul class="devsite-footer-sites-list"> <li class="devsite-footer-sites-item"> <a href="//developer.android.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Android Link" > Android </a> </li> <li class="devsite-footer-sites-item"> <a href="//developer.chrome.com/home" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Chrome Link" > Chrome </a> </li> <li class="devsite-footer-sites-item"> <a href="//firebase.google.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Firebase Link" > Firebase </a> </li> <li class="devsite-footer-sites-item"> <a href="//cloud.google.com" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Google Cloud Platform Link" > Google Cloud Platform </a> </li> <li class="devsite-footer-sites-item"> <a href="//developers.google.com/products/" class="devsite-footer-sites-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer All products Link" > All products </a> </li> </ul> </nav> <nav class="devsite-footer-utility-links" aria-label="Utility links"> <ul class="devsite-footer-utility-list"> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="/terms/" data-category="Site-Wide Custom Events" data-label="Footer Terms link" > Terms </a> </li> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/privacy" data-category="Site-Wide Custom Events" data-label="Footer Privacy link" > Privacy </a> </li> <li class="devsite-footer-utility-item glue-cookie-notification-bar-control"> <a class="devsite-footer-utility-link gc-analytics-event" href="#" data-category="Site-Wide Custom Events" data-label="Footer Manage cookies link" aria-hidden="true" > Manage cookies </a> </li> </ul> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es" >Español</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt" >Português</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> </nav> </div> </devsite-footer-utility> <devsite-panel></devsite-panel> <devsite-concierge data-info-panel data-ai-panel > </devsite-concierge> </section></section> <devsite-sitemask></devsite-sitemask> <devsite-snackbar></devsite-snackbar> <devsite-tooltip ></devsite-tooltip> <devsite-heading-link></devsite-heading-link> <devsite-analytics> <script type="application/json" analytics>[]</script> <script type="application/json" tag-management>{&#34;at&#34;: &#34;True&#34;, &#34;ga4&#34;: [], &#34;ga4p&#34;: [], &#34;gtm&#34;: [{&#34;id&#34;: &#34;GTM-N84485&#34;, &#34;purpose&#34;: 0}], &#34;parameters&#34;: {&#34;internalUser&#34;: &#34;False&#34;, &#34;language&#34;: {&#34;machineTranslated&#34;: &#34;False&#34;, &#34;requested&#34;: &#34;en&#34;, &#34;served&#34;: &#34;en&#34;}, &#34;pageType&#34;: &#34;guide&#34;, &#34;projectName&#34;: &#34;Firebase Test Lab&#34;, &#34;signedIn&#34;: &#34;False&#34;, &#34;tenant&#34;: &#34;firebase&#34;, &#34;recommendations&#34;: {&#34;sourcePage&#34;: &#34;&#34;, &#34;sourceType&#34;: 0, &#34;sourceRank&#34;: 0, &#34;sourceIdenticalDescriptions&#34;: 0, &#34;sourceTitleWords&#34;: 0, &#34;sourceDescriptionWords&#34;: 0, &#34;experiment&#34;: &#34;&#34;}, &#34;experiment&#34;: {&#34;ids&#34;: &#34;&#34;}}}</script> </devsite-analytics> <devsite-badger></devsite-badger> <firebase-gtm></firebase-gtm> <firebase-utm></firebase-utm> <script nonce="/6t0bfYF36MPf9+2+LE6DcSzBX8asw"> (function(d,e,v,s,i,t,E){d['GoogleDevelopersObject']=i; t=e.createElement(v);t.async=1;t.src=s;E=e.getElementsByTagName(v)[0]; E.parentNode.insertBefore(t,E);})(window, document, 'script', 'https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/js/app_loader.js', '[4,"en",null,"/js/devsite_app_module.js","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase","https://firebase-dot-devsite-v2-prod.appspot.com",null,null,["/_pwa/firebase/manifest.json","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/images/video-placeholder.svg","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/favicon.png","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/firebase/images/lockup.svg","https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"],1,null,[1,6,8,12,14,17,21,25,50,52,63,70,75,76,80,87,91,92,93,97,98,100,101,102,103,104,105,107,108,109,110,112,113,116,117,118,120,122,124,125,126,127,129,130,131,132,133,134,135,136,138,140,141,147,148,149,151,152,156,157,158,159,161,163,164,168,169,170,179,180,182,183,186,191,193,196],"AIzaSyAP-jjEJBzmIyKR4F-3XITp8yM9T1gEEI8","AIzaSyB6xiKGDR5O3Ak2okS4rLkauxGUG7XP0hg","firebase.google.com","AIzaSyAQk0fBONSGUqCNznf6Krs82Ap1-NV6J4o","AIzaSyCCxcqdrZ_7QMeLCRY20bh_SXdAYqy70KY",null,null,null,["MiscFeatureFlags__emergency_css","Significatio__enable_by_tenant","Profiles__enable_public_developer_profiles","Profiles__enable_release_notes_notifications","Profiles__enable_recognition_badges","MiscFeatureFlags__enable_firebase_utm","Cloud__enable_llm_concierge_chat","Concierge__enable_concierge","Profiles__enable_developer_profiles_callout","EngEduTelemetry__enable_engedu_telemetry","Search__enable_ai_eligibility_checks","Profiles__enable_profile_collections","Profiles__enable_page_saving","CloudShell__cloud_code_overflow_menu","BookNav__enable_tenant_cache_key","Cloud__enable_cloud_facet_chat","Profiles__require_profile_eligibility_for_signin","MiscFeatureFlags__enable_dark_theme","MiscFeatureFlags__enable_view_transitions","Experiments__reqs_query_experiments","TpcFeatures__enable_mirror_tenant_redirects","Cloud__enable_cloud_dlp_service","Profiles__enable_dashboard_curated_recommendations","Search__enable_ai_search_summaries","MiscFeatureFlags__developers_footer_dark_image","TpcFeatures__enable_required_headers","Cloud__enable_cloud_shell_fte_user_flow","DevPro__enable_cloud_innovators_plus","Concierge__enable_pushui","Profiles__enable_completecodelab_endpoint","Cloud__enable_legacy_calculator_redirect","MiscFeatureFlags__enable_project_variables","Cloud__enable_free_trial_server_call","CloudShell__cloud_shell_button","MiscFeatureFlags__enable_explain_this_code","DevPro__enable_developer_subscriptions","MiscFeatureFlags__developers_footer_image","Analytics__enable_clearcut_logging","Search__enable_page_map","Search__enable_dynamic_content_confidential_banner","MiscFeatureFlags__enable_variable_operator","Cloud__enable_cloud_shell","Cloud__enable_cloudx_ping","Profiles__enable_awarding_url","Cloud__enable_cloudx_experiment_ids","Profiles__enable_complete_playlist_endpoint","Search__enable_suggestions_from_borg"],null,null,"AIzaSyBLEMok-5suZ67qRPzx0qUtbnLmyT_kCVE","https://developerscontentserving-pa.clients6.google.com","AIzaSyCM4QpTRSqP5qI4Dvjt4OAScIN8sOUlO-k","https://developerscontentsearch-pa.clients6.google.com",1,4,null,"https://developerprofiles-pa.clients6.google.com",[4,"firebase","Firebase","firebase.google.com",null,"firebase-dot-devsite-v2-prod.appspot.com",null,null,[1,1,null,null,null,null,null,null,null,null,null,[1],null,null,null,null,null,null,[1],[1,null,null,[1]],null,null,null,[1,null,1],[1,1,null,null,1]],null,[68,null,null,null,null,null,"/images/lockup.svg","/images/touchicon-180.png",null,null,null,1,1,1,null,null,null,null,null,null,null,2,null,null,null,"/images/lockup.svg",[]],[],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[6,1,20,22,23,29,37],null,[[],[1,1]],[[null,null,null,null,["UA-24532603-9"],["GTM-N84485"],null,null,null,null,[["UA-24532603-9",1]],[["GTM-N84485",1]],1],[[2,5],[17,1],[16,2],[46,8],[36,4]],null,1],null,4],null,"pk_live_5170syrHvgGVmSx9sBrnWtA5luvk9BwnVcvIi7HizpwauFG96WedXsuXh790rtij9AmGllqPtMLfhe2RSwD6Pn38V00uBCydV4m"]') </script> <devsite-a11y-announce></devsite-a11y-announce> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10