



  

<!DOCTYPE html>
<html
  lang="en"
  
  data-color-mode="auto" data-light-theme="light" data-dark-theme="dark"
  data-a11y-animated-images="system" data-a11y-link-underlines="true"
  
  >




  <head>
    <meta charset="utf-8">
  <link rel="dns-prefetch" href="https://github.githubassets.com">
  <link rel="dns-prefetch" href="https://avatars.githubusercontent.com">
  <link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com">
  <link rel="dns-prefetch" href="https://user-images.githubusercontent.com/">
  <link rel="preconnect" href="https://github.githubassets.com" crossorigin>
  <link rel="preconnect" href="https://avatars.githubusercontent.com">

<script type="importmap">{"imports":{"react":"https://github.githubassets.com/assets/react-e27d1b3e03961e68.js","react-dom":"https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js","react-dom/client":"https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js","react-is":"https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js","react-reconciler":"https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js","react/compiler-runtime":"https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js","react/jsx-dev-runtime":"https://github.githubassets.com/assets/react-jsx-dev-runtime-ea55d68667d559e5.js","react/jsx-runtime":"https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js","scheduler":"https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js"}}</script>
<meta name="react-profiling" content="0" data-turbo-transient="true" />
<meta name="react-import-map" content="react,react-dom,react-dom/client,react-dom/profiling,react-is,react-reconciler,react/compiler-runtime,react/jsx-dev-runtime,react/jsx-runtime,scheduler@777f63f87cd0" data-turbo-track="reload" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-e27d1b3e03961e68.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-compiler-runtime-4610bd6d3de9c049.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/scheduler-58b860b049ca307c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-e5fd46a22d5c4058.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-dom-client-1b4a3ee065998cea.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-is-e0b593954b4706d8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-jsx-runtime-4915cb0f5b3aff04.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-reconciler-8e99e505c4429605.js" />

  


  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light-99f877e9ddfc0e51.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/light_high_contrast-48fdd0811afbab3c.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark-79ad2ace604703b3.css" /><link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/dark_high_contrast-24484a076f02295f.css" /><link data-color-theme="light" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light-99f877e9ddfc0e51.css" /><link data-color-theme="light_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_high_contrast-48fdd0811afbab3c.css" /><link data-color-theme="light_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind-f4bf1142976e4bbf.css" /><link data-color-theme="light_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_colorblind_high_contrast-f661b49995ba0bd8.css" /><link data-color-theme="light_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia-0b38d22346321c92.css" /><link data-color-theme="light_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/light_tritanopia_high_contrast-f1c62c9e70259b9f.css" /><link data-color-theme="dark" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark-79ad2ace604703b3.css" /><link data-color-theme="dark_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_high_contrast-24484a076f02295f.css" /><link data-color-theme="dark_colorblind" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind-f50cacf0a86b9929.css" /><link data-color-theme="dark_colorblind_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_colorblind_high_contrast-e61d4f4ca17852c2.css" /><link data-color-theme="dark_tritanopia" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia-39c10993d5603fac.css" /><link data-color-theme="dark_tritanopia_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_tritanopia_high_contrast-73236c840c0c7d90.css" /><link data-color-theme="dark_dimmed" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed-0de76f07cc035b10.css" /><link data-color-theme="dark_dimmed_high_contrast" crossorigin="anonymous" media="all" rel="stylesheet" data-href="https://github.githubassets.com/assets/dark_dimmed_high_contrast-fd1500c8744e40d6.css" />

  <style type="text/css">
    :root {
      --tab-size-preference: 4;
    }

    pre, code {
      tab-size: var(--tab-size-preference);
    }
  </style>

    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-primitives-ed9ca172356fd545.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-1d2c7f7b52a6068b.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-54ba76e934a49d7c.css" />
    <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/github-88fc7764b4deb69a.css" />
  <link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/repository-11ee8a031c040c1a.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-2d56bdb0166c0238.css" />

  

  <script type="application/json" id="client-env">{"locale":"en","featureFlags":["actions_enable_background_steps","actions_new_hosted_runner_image_select_sizes_and_versions","activity_diff_file_tree","activity_repos_file_tree","activity_repos_overview_header","activity_repos_overview_sidebar","agent_author_search_expansion","agent_author_search_expansion_ui_pulls","alternate_user_config_repo","async_conversion_coverage_enabled","billing_billable_licenses_cost_center_bucket_fix","billing_budget_expiration","billing_cost_center_list_assigned_resources","billing_discount_threshold_notification","cca_show_aic_usage_per_session","code_quality_enablement_banner_targeting","code_quality_remove_preview","code_view_raf_sticky_lines","codespaces_prebuild_region_target_update","coding_agent_third_party_model_ui","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_automations_pagination","copilot_chat_clear_model_selection_for_default_change","copilot_chat_compact_tables","copilot_chat_header_reorder","copilot_chat_max_upsell","copilot_chat_minimize_contextual","copilot_chat_model_picker_promotions","copilot_chat_models_browser_cache","copilot_chat_new_topic_nudge","copilot_chat_reduce_quota_checks","copilot_chat_vision_dotcom_chat_ga_gate","copilot_chat_vision_preview_gate","copilot_css_textarea_autosize","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_removal_on_marketplace","copilot_fix_failed_workflows_all_skus","copilot_ftp_hyperspace_upgrade_prompt","copilot_hide_hovercard","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded_draggable","copilot_immersive_embedded_header_button","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_suggestion_pills","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_agent_merge_fix_ci","copilot_mission_control_agent_merge_resolve_conflicts","copilot_mission_control_agents_repository_enablement","copilot_mission_control_early_stop","copilot_mission_control_environment_list_icons","copilot_mission_control_managed_sandbox_environments","copilot_mission_control_needs_attention","copilot_mission_control_reasoning_effort","copilot_mission_control_repo_hovercards","copilot_mission_control_sandbox_client_side_clone","copilot_mission_control_sandbox_remote_bypass","copilot_mission_control_session_filters","copilot_mission_control_task_alive_updates","copilot_mission_control_task_sharing","copilot_org_policy_page_focus_mode","copilot_pr_chat_enhancements","copilot_prominent_upgrade_button","copilot_resource_panel","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_authorization_status_ui","copilot_swe_agent_automation_resource_scoped_writes","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_issue_comment_trigger","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_pull_request_comment_trigger","copilot_swe_agent_pull_request_merged_trigger","copilot_swe_agent_pull_request_opened_trigger","copilot_swe_agent_pull_request_synchronize_trigger","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_task_scoped_alive_channel","copilot_token_based_billing","copilot_unconfigured_is_inherited","copilot_user_can_upgrade_plan_field","copilot_workbench_sunset","copilot_workbench_sunset_redirect","copilot_workbench_ubb","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","flex_suite_disable_river_accordion_dither","glc_code_quality_repo_settings_workflow_config","hide_github_models_ui","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","in_product_messaging_datadog_monitoring","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_fields_multi_select","issue_inline_avatars","issue_pinned_views","issue_pinned_views_optimistic_updates","issue_relative_time_micro","issues_dashboard_sso_structured_errors","issues_expanded_file_types","issues_hide_closed_sub_issues","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","labels_archiving","labels_archiving_info","landing_pages_ninetailed","lifecycle_label_name_updates","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_lazy_hydrate_agent_tasks","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_queue_restricted_pushers_warning","merge_status_checks_refetch_dedupe","merge_status_header_feedback","oauth_authorize_clickjacking_protection","octocaptcha_origin_optimization","primer_react_css_anchor_positioning","primer_react_merged_forwarded_refs","prs_copilot_app_open_action","prs_css_anchor_positioning","pull_request_copilot_attribution_header","pull_request_overview_panel_edit_description","pull_request_persister","pull_request_stacks_feedback_dialog","pull_request_stacks_rebase_conflict_instructions","pull_request_virtualization_image_estimate","pull_request_virtualization_scroll_compensation","pull_request_virtualization_scroll_intent","pulls_dashboard_sidebar_layout","quick_search_lazy_suggestions","react_blob_isolate_code_lines","react_blob_ssr_content_visibility","react_data_router_tanstack_allowed","react_query_props_with_key","react_sandbox_future_tanstack","repo_app","repo_app_actions_workflows","repo_app_agents","repo_app_commits","repo_app_issues","repo_app_pull_requests","repo_app_turbo","repo_issues_sidebar_layout","repo_overview_ask_copilot","repo_pulls_dashboard_persistence","repos_contributors_limited_default_range","review_involves_filter","rule_ignored_file_paths","rulesets_actor_list_editor","sample_network_conn_type","security_center_artifact_filters_popover","see_who_reacted","semantic_similarity_duplicate_issue_detection","session_logs_ungroup_reasoning_text","set_sha256_on_repo_creation_form","site_banner_desktop_copilot_app","site_ghca_pixel_mona","site_github_app_ga_page","site_github_app_ga_page_highlight","site_github_app_mobile_native_share","site_global_banner_dev_days_attendee","site_global_banner_learn_copilot_sdk","site_global_nav_spark_models_removed","spark_prompt_secret_scanning","spark_server_connection_status","suggest_custom_property_values_copilot","suppress_automated_browser_vitals","swp_forms_disable_octocaptcha","thread_resolution_reason","ui_service_referrer_metrics","ui_service_staleness_detection","update_issue_suggestions","user_code_paste_ux","viewscreen_sandbox","warn_inaccessible_attachments","webp_support","workbench_store_readonly","react_import_map","react_import_map"],"githubDomain":"https://github.com","copilotApiOverrideUrl":"https://api.githubcopilot.com","cmcApiUrl":"https://api.github.com/cmc_internal/api"}</script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/high-contrast-cookie-e3d808ee18eb9784.js"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-runtime-d36c2e96db74cee4.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-foundation-89338d13d121427c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/app-runtime-d8e4e5512b66f1d2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fetch-utilities-ef80792c471f3488.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ser-564408e9198dff6d.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/environment-6c93cc570c2f2713.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/app-runtime.47a3599624d63f20.module.css" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/catalyst-86a8f5de995615f8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/selector-observer-e88088f989b27670.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/relative-time-element-7cdf4e0db98b997c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/by-6b3c07383371bf58.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ja9-36f036c13c2e3a4c.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/kw-866fd9513ae95106.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/r1-b075aab3204f32f9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jz5-7c5d1669717041f8.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hj-5126390ff433704d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j05-dce4d588268f0f7e.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/github-elements-9136c3da72ef47e0.js" defer="defer"></script>
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/element-registry-5cfb4a22c59d1609.js" defer="defer"></script>
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/runtime-helpers-6df03a157bacbc44.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/aria-live-76b18916d0c8ec4d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hotkey-5109c77d7ac61078.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/react-core-29b8ffcaab7c3949.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/04-a76c47ec12c12e01.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ur-024971cb63acad59.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4t-364e19c63d726e9a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6ny-c969fbae697a356f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/yhq-3a209035a30b1a09.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/z1v-da5b33b877bfa358.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wo-09f85d22a6c8931b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/9y-81cfe57dc9040f3e.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j0-41a4cf04cbd99503.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0p-81491ed0d9d666e2.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/behaviors-e86299772805b3b3.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/react-core.db13aa11eb5412b2.module.css" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-menu-a303bfa3d4af14c5.js" defer="defer"></script>
  
  <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/primer-react-050aafaffcbc0f54.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ncx-9a860680a5f230b9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j6-363f0ebf4f62f310.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/t7l-bf6f21d7e7a43c35.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fe-7576d9b281e2106a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wsr-5fd3071e5a9061ab.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0n-ecadb2ffe6b01ba2.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xv-51cb34754bda73a9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/n4u-6317ce1c31aed1db.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/j8s-d05eedc69cebc200.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/la-de176c4ee471f2b3.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/pa9-63a2449f68fddcc9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qk-69b7a09c43e10e06.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/6ko-674c1ec5588e9f0f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/nsi-926ffbc13301c5b7.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/mgq-93f58f229b2328b4.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/on-75d8015f7c16be87.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bi0-e2f78de823e39ca9.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/b1-1dbc371cef78c3c1.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0l-60a7083fe8307476.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/c2z-c92998400310b94b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/f9-038758dcbfe08dab.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0k-b7df0a74912a42bf.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/sp-2bbb73a69162e23b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/og-93ae8b358505d372.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/q5-fc1f2b54f1d10663.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ec-ec74cb1fa6c31a3f.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/du-bbe0f39cd2abe9a0.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ql0-6accb9e40c25a6a5.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/20-32a6db98bc57337d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/dsj-4cca625a20b72565.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/wp-9f5235d335ab624b.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/e84-4da7096eb6b55d6d.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0pz-90009c6b3d9415c6.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7mh-77fafa8751caee98.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/bsb-4f4ac8c20da73fac.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/46-90fb1c98afc2cd5a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/jga-3f6576d6f86d4e43.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/ax-0ad16095945fc6f4.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/0dh-eb608edac481e761.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/xc-f5d51b571cd317cb.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/7cv-33c444fbc72b9998.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4b-c63a3f3820a90d31.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/qv-bdafe2897b1bc43a.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/gtp-0eb27f0896440617.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/code-view-a4ab686d375b875c.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.7c5f404947919942.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/ql0.bd9e6b542f167fd8.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/46.3e560835284be460.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/xc.13e027137438fd9f.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/4b.e524e9f270f17ecc.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/qv.1bac5eeb7156cd97.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/code-view.f3937ee8717738ed.module.css" />

  <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/hu-1fc0b2a167afc025.js" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/uul-06c73d3dea5f5318.js" />
<script crossorigin="anonymous" type="module" src="https://github.githubassets.com/assets/notifications-subscriptions-menu-9cdb71a0a0f38218.js" defer="defer"></script>
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.7c5f404947919942.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/notifications-subscriptions-menu.89410a16a27828fc.module.css" />


  <title>FirebaseUI-Android/database/README.md at master · firebase/FirebaseUI-Android · GitHub</title>



  <meta name="route-pattern" content="/:user_id/:repository/blob/*name(/*path)" data-turbo-transient>
  <meta name="route-controller" content="blob" data-turbo-transient>
  <meta name="route-action" content="show" data-turbo-transient>
  <meta name="fetch-nonce" content="v2:45a0a27a-909d-f88a-6773-57f2e6405273">

    
  <meta name="current-catalog-service-hash" content="f3abb0cc802f3d7b95fc8762b94bdcb13bf39634c40c357301c4aa1d67a256fb">


  <meta name="request-id" content="CC72:150CE6:4A70AE:41519D:6AA97512" data-pjax-transient="true"/><meta name="html-safe-nonce" content="30847e397dc3718b3aa5b4c1f8b3738f4d974c753a66bb84afc5bbf52f00a8ef" data-pjax-transient="true"/><meta name="visitor-payload" content="eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDQzcyOjE1MENFNjo0QTcwQUU6NDE1MTlEOjZBQTk3NTEyIiwidmlzaXRvcl9pZCI6IjkwNjk1ODA4NjkwNzExMDczNDYiLCJyZWdpb25fZWRnZSI6ImZyYSIsInJlZ2lvbl9yZW5kZXIiOiJmcmEifQ==" data-pjax-transient="true"/><meta name="visitor-hmac" content="00020ad8a74291794a19c2e9ebbbb94f5e74484f38e08f39afa1b43ab3ee829e" data-pjax-transient="true"/>


    <meta name="hovercard-subject-tag" content="repository:38835213" data-turbo-transient>


  <meta name="github-keyboard-shortcuts" content="repository,source-code,file-tree,copilot" data-turbo-transient="true" />
  

  <meta name="selected-link" value="repo_source" data-turbo-transient>
  <link rel="assets" href="https://github.githubassets.com/">

    <meta name="google-site-verification" content="Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I">

<meta name="octolytics-url" content="https://collector.github.com/github/collect" />





  <meta name="analytics-location" content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-turbo-transient="true" />

  




    <meta name="user-login" content="">

  

    <meta name="viewport" content="width=device-width">

    

      <meta name="description" content="Optimized UI components for Firebase. Contribute to firebase/FirebaseUI-Android development by creating an account on GitHub.">

      <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">

    <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
    <meta property="fb:app_id" content="1401488693436528">
    <meta name="apple-itunes-app" content="app-id=1477376905, app-argument=https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md" />

      <meta name="twitter:image" content="https://opengraph.githubassets.com/362f8dc07f60320a1a7f1c5d00e9e3488591e576ab53a60f34aeb967f6a2e0bf/firebase/FirebaseUI-Android" /><meta name="twitter:site" content="@github" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="FirebaseUI-Android/database/README.md at master · firebase/FirebaseUI-Android" /><meta name="twitter:description" content="Optimized UI components for Firebase. Contribute to firebase/FirebaseUI-Android development by creating an account on GitHub." />
  <meta property="og:image" content="https://opengraph.githubassets.com/362f8dc07f60320a1a7f1c5d00e9e3488591e576ab53a60f34aeb967f6a2e0bf/firebase/FirebaseUI-Android" /><meta property="og:image:alt" content="Optimized UI components for Firebase. Contribute to firebase/FirebaseUI-Android development by creating an account on GitHub." /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="600" /><meta property="og:site_name" content="GitHub" /><meta property="og:type" content="object" /><meta property="og:title" content="FirebaseUI-Android/database/README.md at master · firebase/FirebaseUI-Android" /><meta property="og:url" content="https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md" /><meta property="og:description" content="Optimized UI components for Firebase. Contribute to firebase/FirebaseUI-Android development by creating an account on GitHub." />
  




      <meta name="hostname" content="github.com">



        <meta name="expected-hostname" content="github.com">


  <meta http-equiv="x-pjax-version" content="49be2262d587a131450d70b8d45705729e15f30adc7a49e415cbdfe189c0a7bd" data-turbo-track="reload">
  <meta http-equiv="x-pjax-csp-version" content="f2311ccc2e94cef09d9c62c8c090301d08823a2fd66b86a913b7d968c86acb1a" data-turbo-track="reload">
  <meta http-equiv="x-pjax-css-version" content="fd80f4397e6b366d79cd8ab0cc06c0f64e6a731ebf6ac8fbb538416234459325" data-turbo-track="reload">
  <meta http-equiv="x-pjax-js-version" content="0222d07c6e659b8819bcc5f0e4c766db7dd6b3235b5f8a6e4c5c6db4dfcf145e" data-turbo-track="reload">

  <meta name="turbo-cache-control" content="no-preview" data-turbo-transient="">

      <meta name="turbo-cache-control" content="no-cache" data-turbo-transient>

    <meta data-hydrostats="publish">

  <meta name="go-import" content="github.com/firebase/FirebaseUI-Android git https://github.com/firebase/FirebaseUI-Android.git">

  <meta name="octolytics-dimension-user_id" content="1335026" /><meta name="octolytics-dimension-user_login" content="firebase" /><meta name="octolytics-dimension-repository_id" content="38835213" /><meta name="octolytics-dimension-repository_nwo" content="firebase/FirebaseUI-Android" /><meta name="octolytics-dimension-repository_public" content="true" /><meta name="octolytics-dimension-repository_is_fork" content="false" /><meta name="octolytics-dimension-repository_network_root_id" content="38835213" /><meta name="octolytics-dimension-repository_network_root_nwo" content="firebase/FirebaseUI-Android" />
  



    

    <meta name="turbo-body-classes" content="logged-out env-production page-responsive">
  <meta name="disable-turbo" content="false">


  <meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">


  <meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">

  <meta name="release" content="8af1d6ddd7587673b31fc1e5e8eb3c4bc97d1cab" data-turbo-track="reload">
  <meta name="ui-target" content="full">

  <link rel="mask-icon" href="https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg" color="#000000">
  <link rel="alternate icon" class="js-site-favicon" type="image/png" href="https://github.githubassets.com/favicons/favicon.png">
  <link rel="icon" class="js-site-favicon" type="image/svg+xml" href="https://github.githubassets.com/favicons/favicon.svg" data-base-href="https://github.githubassets.com/favicons/favicon">

<meta name="theme-color" content="#1e2327">
<meta name="color-scheme" content="light dark" />


  <link rel="manifest" href="/manifest.json" crossOrigin="use-credentials">

  </head>

  <body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
    <div data-turbo-body class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
      <div id="__primerPortalRoot__" style="z-index: 1000; position: absolute; width: 100%;" data-turbo-permanent></div>
      

    <div class="position-relative header-wrapper js-header-wrapper ">
      <a href="#start-of-content" data-skip-target-assigned="false" class="px-2 tmp-py-4 color-bg-accent-emphasis color-fg-on-emphasis show-on-focus js-skip-to-content">Skip to content</a>

      <span data-view-component="true" class="progress-pjax-loader Progress position-fixed width-full">
    <span style="width: 0%;" data-view-component="true" class="Progress-item progress-pjax-loader-bar left-0 top-0 color-bg-accent-emphasis"></span>
</span>      
      <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/l7j-2ddd8b435dadae28.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog-de8e6cab9dee9bea.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.7c5f404947919942.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/keyboard-shortcuts-dialog.0497dd4c65ae3400.module.css" />

<react-partial
  partial-name="keyboard-shortcuts-dialog"
  data-ssr="false"
  data-attempted-ssr="false"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"docsUrl":"https://docs.github.com/get-started/accessibility/keyboard-shortcuts"}}</script>
  <div data-target="react-partial.reactRoot"></div>
</react-partial>





      

          

                <link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/2l-cbdcab386be8ed25.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/i26-e41bee64286a7613.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/fz5-23f28c0f388769c9.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/lht-26506ea833dda5be.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/p1-76a75a6081059b19.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/3d-82c347d20a13fb90.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/tua-c4ca62c5e0e0318e.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/4s-0fa28f31e42d2b12.js" fetchpriority="low" />
<link crossorigin="anonymous" rel="modulepreload" href="https://github.githubassets.com/assets/marketing-header-894af0c99c741043.js" fetchpriority="low" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-css.7c5f404947919942.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/primer-react-brand-css.6a01c236ff527e7e.module.css" />
<link crossorigin="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/4s.0475f8e2181c4fb1.module.css" />

<react-partial
  partial-name="marketing-header"
  data-ssr="true"
  data-attempted-ssr="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-partial.embeddedData">{"props":{"color_mode":"dark","logged_in":false,"marketing_page":false,"home_path":"/","login_path":"/login?return_to=https%3A%2F%2Fgithub.com%2Ffirebase%2FFirebaseUI-Android%2Fblob%2Fmaster%2Fdatabase%2FREADME.md","signup_path":"/signup?ref_cta=Sign+up\u0026ref_loc=header+logged+out\u0026ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow\u0026source=header-repo\u0026source_repo=firebase%2FFirebaseUI-Android","signup_enabled":true,"is_signup_controller":false,"show_search_and_nav":true,"hide_search":false,"private_mode_enabled":false,"should_use_dotcom_links":true,"auth_hydro_click":"{\"event_type\":\"authentication.click\",\"payload\":{\"location_in_page\":\"site header menu\",\"repository_id\":null,\"auth_type\":\"SIGN_UP\",\"originating_url\":\"https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md\",\"user_id\":null}}","auth_hydro_click_hmac":"16f0d2af3561e6cd5079dcb9462de78d2d4e89acf0e47ecf358da01a3700d0e2","overlay":false,"fixed":false}}</script>
  <div data-target="react-partial.reactRoot"><div data-color-mode="dark" data-light-theme="light" data-dark-theme="dark"><header class="MarketingHeader-module__root__Tk7n3 HeaderMktg header-logged-out" role="banner" data-marketing-header="true" data-color-mode="dark" data-light-theme="light" data-dark-theme="dark" data-is-top="true"><h2 class="MarketingHeader-module__visuallyHidden__sqKsl">Navigation Menu</h2><button type="button" class="MarketingHeader-module__backdrop__sw4RU" aria-label="Close navigation menu"></button><div class="MarketingHeader-module__bar__mBSyE"><div class="MarketingHeader-module__topRow__yeury"><div class="MarketingHeader-module__toggleSlot__hDxbh"><button type="button" class="HeaderMenuToggle-module__toggle__i8EiC" aria-label="Toggle navigation" aria-expanded="false"><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span><span class="HeaderMenuToggle-module__toggleBar__jVN0H"></span></button></div><a href="/" aria-label="Homepage" class="HeaderLogo-module__logo__UFyHI" data-analytics-event="{&quot;action&quot;:&quot;homepage&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;logo&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;homepage_link_logo_header&quot;}"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github" viewBox="0 0 24 24" width="32" height="32" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path></svg></a><div class="AuthCTAs-module__mobileActions__NNzeV"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/login?return_to=https%3A%2F%2Fgithub.com%2Ffirebase%2FFirebaseUI-Android%2Fblob%2Fmaster%2Fdatabase%2FREADME.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="16f0d2af3561e6cd5079dcb9462de78d2d4e89acf0e47ecf358da01a3700d0e2"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_3dd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_3dd_">Appearance settings</div></div></div><div class="MarketingHeader-module__menu__GIy3y"><div class="MarketingHeader-module__menuWrapper__owstH"><nav class="MarketingNavigation-module__nav__W0KYY" aria-label="Global"><ul class="MarketingNavigation-module__list__tFbMb"><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_nd_">Platform<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5knd_">AI CODE CREATION</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot" data-analytics-event="{&quot;action&quot;:&quot;github_copilot&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>GitHub Copilot</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Write better code with AI</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/ai/github-app" data-analytics-event="{&quot;action&quot;:&quot;github_copilot_app&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_copilot_app_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mark-github NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656"></path></svg>GitHub Copilot app</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Direct agents from issue to merge</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/mcp" data-analytics-event="{&quot;action&quot;:&quot;mcp_registry&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;mcp_registry_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-mcp NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.52 1.12a3.578 3.578 0 0 1 6.078 2.98 3.578 3.578 0 0 1 2.982 6.08l-3.292 3.293a.252.252 0 0 0 0 .354l.843.843a.749.749 0 1 1-1.06 1.06l-.844-.843a1.75 1.75 0 0 1 0-2.474L13.52 9.12a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0L7.731 9.03A.75.75 0 0 1 6.67 7.97l2.85-2.85a2.08 2.08 0 0 0 0-2.94 2.08 2.08 0 0 0-2.94 0l-4.799 4.8A.75.75 0 0 1 .72 5.92Z"></path><path d="M7.52 3.12a.749.749 0 1 1 1.06 1.06L5.731 7.03A2.079 2.079 0 0 0 8.67 9.97l2.85-2.85a.749.749 0 1 1 1.06 1.06l-2.849 2.85A3.578 3.578 0 0 1 4.67 5.97Z"></path></svg>MCP Registry</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Integrate external tools</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9knd_">DEVELOPER WORKFLOWS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9knd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/actions" data-analytics-event="{&quot;action&quot;:&quot;actions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;actions_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-workflow NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h3.5C6.216 0 7 .784 7 1.75v3.5A1.75 1.75 0 0 1 5.25 7H4v4a1 1 0 0 0 1 1h4v-1.25C9 9.784 9.784 9 10.75 9h3.5c.966 0 1.75.784 1.75 1.75v3.5A1.75 1.75 0 0 1 14.25 16h-3.5A1.75 1.75 0 0 1 9 14.25v-.75H5A2.5 2.5 0 0 1 2.5 11V7h-.75A1.75 1.75 0 0 1 0 5.25Zm1.75-.25a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Zm9 9a.25.25 0 0 0-.25.25v3.5c0 .138.112.25.25.25h3.5a.25.25 0 0 0 .25-.25v-3.5a.25.25 0 0 0-.25-.25Z"></path></svg>Actions</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Automate any workflow</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/codespaces" data-analytics-event="{&quot;action&quot;:&quot;codespaces&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;codespaces_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codespaces NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 11.25c0-.966.784-1.75 1.75-1.75h12.5c.966 0 1.75.784 1.75 1.75v3A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm2-9.5C2 .784 2.784 0 3.75 0h8.5C13.216 0 14 .784 14 1.75v5a1.75 1.75 0 0 1-1.75 1.75h-8.5A1.75 1.75 0 0 1 2 6.75Zm1.75-.25a.25.25 0 0 0-.25.25v5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5a.25.25 0 0 0-.25-.25Zm-2 9.5a.25.25 0 0 0-.25.25v3c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25v-3a.25.25 0 0 0-.25-.25Z"></path><path d="M7 12.75a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm-4 0a.75.75 0 0 1 .75-.75h.5a.75.75 0 0 1 0 1.5h-.5a.75.75 0 0 1-.75-.75Z"></path></svg>Codespaces</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Instant dev environments</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/issues" data-analytics-event="{&quot;action&quot;:&quot;issues&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;issues_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-issue-opened NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path></svg>Issues</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Plan and track work</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-review" data-analytics-event="{&quot;action&quot;:&quot;code_review&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_review_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path></svg>Code Review</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Manage code changes</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/code-quality" data-analytics-event="{&quot;action&quot;:&quot;code_quality&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_quality_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-codescan-checkmark NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.28 6.28a.75.75 0 1 0-1.06-1.06L6.25 8.19l-.97-.97a.75.75 0 0 0-1.06 1.06l1.5 1.5a.75.75 0 0 0 1.06 0l3.5-3.5Z"></path><path d="M7.5 15a7.5 7.5 0 1 1 5.807-2.754l2.473 2.474a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2.474-2.473A7.472 7.472 0 0 1 7.5 15Zm0-13.5a6 6 0 1 0 4.094 10.386.748.748 0 0 1 .293-.292 6.002 6.002 0 0 0 1.117-6.486A6.002 6.002 0 0 0 7.5 1.5Z"></path></svg>Code Quality</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enforce quality at merge</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dknd_">APPLICATION SECURITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Find and fix vulnerabilities</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/code-security" data-analytics-event="{&quot;action&quot;:&quot;code_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;code_security_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-code-square NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25Zm7.47 3.97a.75.75 0 0 1 1.06 0l2 2a.75.75 0 0 1 0 1.06l-2 2a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L10.69 8 9.22 6.53a.75.75 0 0 1 0-1.06ZM6.78 6.53 5.31 8l1.47 1.47a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215l-2-2a.75.75 0 0 1 0-1.06l2-2a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>Code security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Secure your code as you build</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security/secret-protection" data-analytics-event="{&quot;action&quot;:&quot;secret_protection&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;secret_protection_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-lock NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M4 4a4 4 0 0 1 8 0v2h.25c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 12.25 15h-8.5A1.75 1.75 0 0 1 2 13.25v-5.5C2 6.784 2.784 6 3.75 6H4Zm8.25 3.5h-8.5a.25.25 0 0 0-.25.25v5.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25ZM10.5 6V4a2.5 2.5 0 1 0-5 0v2Z"></path></svg>Secret protection</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Stop leaks before they start</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ NavGroup-module__hasSeparator__FnMrN"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_hknd_">EXPLORE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_hknd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/why-github" data-analytics-event="{&quot;action&quot;:&quot;why_github&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;why_github_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Why GitHub</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog" data-analytics-event="{&quot;action&quot;:&quot;blog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;blog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Blog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://github.blog/changelog" data-analytics-event="{&quot;action&quot;:&quot;changelog&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;changelog_link_platform_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Changelog</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/marketplace" data-analytics-event="{&quot;action&quot;:&quot;marketplace&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;marketplace_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Marketplace</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/features" data-analytics-event="{&quot;action&quot;:&quot;view_all_features&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;platform&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_features_link_platform_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all features</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_17d_">Solutions<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_17d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5l7d_">BY COMPANY SIZE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprises&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprises_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Enterprises</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/team" data-analytics-event="{&quot;action&quot;:&quot;small_and_medium_teams&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;small_and_medium_teams_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Small and medium teams</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/enterprise/startups" data-analytics-event="{&quot;action&quot;:&quot;startups&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;startups_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Startups</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/nonprofits" data-analytics-event="{&quot;action&quot;:&quot;nonprofits&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;nonprofits_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Nonprofits</span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9l7d_">BY USE CASE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9l7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/app-modernization" data-analytics-event="{&quot;action&quot;:&quot;app_modernization&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;app_modernization_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">App Modernization</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devsecops" data-analytics-event="{&quot;action&quot;:&quot;devsecops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devsecops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevSecOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/use-case/ci-cd" data-analytics-event="{&quot;action&quot;:&quot;ci/cd&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ci/cd_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">CI/CD</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/use-case" data-analytics-event="{&quot;action&quot;:&quot;view_all_use_cases&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_use_cases_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all use cases</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dl7d_">BY INDUSTRY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dl7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/healthcare" data-analytics-event="{&quot;action&quot;:&quot;healthcare&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;healthcare_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Healthcare</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/financial-services" data-analytics-event="{&quot;action&quot;:&quot;financial_services&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;financial_services_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Financial services</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/manufacturing" data-analytics-event="{&quot;action&quot;:&quot;manufacturing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;manufacturing_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Manufacturing</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/industry/government" data-analytics-event="{&quot;action&quot;:&quot;government&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;government_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Government</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions/industry" data-analytics-event="{&quot;action&quot;:&quot;view_all_industries&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_industries_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all industries</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/solutions" data-analytics-event="{&quot;action&quot;:&quot;view_all_solutions&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;solutions&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_solutions_link_solutions_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all solutions</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_1nd_">Resources<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_1nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5lnd_">EXPLORE BY TOPIC</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=ai" data-analytics-event="{&quot;action&quot;:&quot;ai&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ai_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">AI</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=software-development" data-analytics-event="{&quot;action&quot;:&quot;software_development&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;software_development_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Software Development</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=devops" data-analytics-event="{&quot;action&quot;:&quot;devops&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;devops_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">DevOps</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/articles?topic=security" data-analytics-event="{&quot;action&quot;:&quot;security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources/articles" data-analytics-event="{&quot;action&quot;:&quot;view_all_topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_topics_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all topics</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9lnd_">EXPLORE BY TYPE</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9lnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/customer-stories" data-analytics-event="{&quot;action&quot;:&quot;customer_stories&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_stories_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer stories</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/events" data-analytics-event="{&quot;action&quot;:&quot;events__webinars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;events__webinars_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Events &amp; webinars</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/resources/whitepapers" data-analytics-event="{&quot;action&quot;:&quot;ebooks__reports&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;ebooks__reports_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Ebooks &amp; reports</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/solutions/executive-insights" data-analytics-event="{&quot;action&quot;:&quot;business_insights&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;business_insights_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Business insights</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://skills.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_skills&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_skills_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Skills</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dlnd_">SUPPORT &amp; SERVICES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dlnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://docs.github.com" data-analytics-event="{&quot;action&quot;:&quot;documentation&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;documentation_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Documentation</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://support.github.com" data-analytics-event="{&quot;action&quot;:&quot;customer_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;customer_support_link_resources_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Customer support</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/orgs/community/discussions" data-analytics-event="{&quot;action&quot;:&quot;community_forum&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;community_forum_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Community forum</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trust-center" data-analytics-event="{&quot;action&quot;:&quot;trust_center&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trust_center_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trust center</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/partners" data-analytics-event="{&quot;action&quot;:&quot;partners&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;partners_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Partners</span></a></li></ul></div></li></ul><div class="NavDropdown-module__trailingLinkContainer__VgJGL"><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--arrow-end___esdN8" href="https://github.com/resources" data-analytics-event="{&quot;action&quot;:&quot;view_all_resources&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;resources&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;view_all_resources_link_resources_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">View all resources</span><svg class="Primer_Brand__ExpandableArrow-module__ExpandableArrow___aaZs9 Primer_Brand__Link-module__Link-arrow___yd78i" width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true" focusable="false"><path fill="currentColor" d="M7.28033 3.21967C6.98744 2.92678 6.51256 2.92678 6.21967 3.21967C5.92678 3.51256 5.92678 3.98744 6.21967 4.28033L7.28033 3.21967ZM11 8L11.5303 8.53033C11.8232 8.23744 11.8232 7.76256 11.5303 7.46967L11 8ZM6.21967 11.7197C5.92678 12.0126 5.92678 12.4874 6.21967 12.7803C6.51256 13.0732 6.98744 13.0732 7.28033 12.7803L6.21967 11.7197ZM6.21967 4.28033L10.4697 8.53033L11.5303 7.46967L7.28033 3.21967L6.21967 4.28033ZM10.4697 7.46967L6.21967 11.7197L7.28033 12.7803L11.5303 8.53033L10.4697 7.46967Z"></path><path class="Primer_Brand__ExpandableArrow-module__ExpandableArrow-stem___0K8Hz" stroke="currentColor" d="M1.75 8H11" stroke-width="1.5" stroke-linecap="round"></path></svg></a></div></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_27d_">Open Source<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_27d_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5m7d_">COMMUNITY</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/open-source/sponsors" data-analytics-event="{&quot;action&quot;:&quot;github_sponsors&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_sponsors_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sponsor-tiers NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.586 1C12.268 1 13.5 2.37 13.5 4.25c0 1.745-.996 3.359-2.622 4.831-.166.15-.336.297-.509.438l1.116 5.584a.75.75 0 0 1-.991.852l-2.409-.876a.25.25 0 0 0-.17 0l-2.409.876a.75.75 0 0 1-.991-.852L5.63 9.519a13.78 13.78 0 0 1-.51-.438C3.497 7.609 2.5 5.995 2.5 4.25 2.5 2.37 3.732 1 5.414 1c.963 0 1.843.403 2.474 1.073L8 2.198l.112-.125a3.385 3.385 0 0 1 2.283-1.068L10.586 1Zm-3.621 9.495-.718 3.594 1.155-.42a1.75 1.75 0 0 1 1.028-.051l.168.051 1.154.42-.718-3.592c-.199.13-.37.235-.505.314l-.169.097a.75.75 0 0 1-.72 0 9.54 9.54 0 0 1-.515-.308l-.16-.105ZM10.586 2.5c-.863 0-1.611.58-1.866 1.459-.209.721-1.231.721-1.44 0C7.025 3.08 6.277 2.5 5.414 2.5 4.598 2.5 4 3.165 4 4.25c0 1.23.786 2.504 2.128 3.719.49.443 1.018.846 1.546 1.198l.325.21.076-.047.251-.163a13.341 13.341 0 0 0 1.546-1.198C11.214 6.754 12 5.479 12 4.25c0-1.085-.598-1.75-1.414-1.75Z"></path></svg>GitHub Sponsors</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Fund open source developers</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9m7d_">PROGRAMS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9m7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://securitylab.github.com" data-analytics-event="{&quot;action&quot;:&quot;security_lab&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;security_lab_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Security Lab</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://maintainers.github.com" data-analytics-event="{&quot;action&quot;:&quot;maintainer_community&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;maintainer_community_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Maintainer Community</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://stars.github.com" data-analytics-event="{&quot;action&quot;:&quot;github_stars&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_stars_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">GitHub Stars</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 Primer_Brand__Link-module__Link--is-external___xsncV" href="https://archiveprogram.github.com" data-analytics-event="{&quot;action&quot;:&quot;archive_program&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;archive_program_link_open_source_navbar&quot;}" target="_blank" rel="noreferrer"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Archive Program</span><svg data-component="Octicon" focusable="false" aria-label="External link" class="octicon octicon-link-external" role="img" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.75 2h3.5a.75.75 0 0 1 0 1.5h-3.5a.25.25 0 0 0-.25.25v8.5c0 .138.112.25.25.25h8.5a.25.25 0 0 0 .25-.25v-3.5a.75.75 0 0 1 1.5 0v3.5A1.75 1.75 0 0 1 12.25 14h-8.5A1.75 1.75 0 0 1 2 12.25v-8.5C2 2.784 2.784 2 3.75 2Zm6.854-1h4.146a.25.25 0 0 1 .25.25v4.146a.25.25 0 0 1-.427.177L13.03 4.03 9.28 7.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.75-3.75-1.543-1.543A.25.25 0 0 1 10.604 1Z"></path></svg></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_dm7d_">REPOSITORIES</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_dm7d_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/topics" data-analytics-event="{&quot;action&quot;:&quot;topics&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;topics_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Topics</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/trending" data-analytics-event="{&quot;action&quot;:&quot;trending&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;trending_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Trending</span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0" href="https://github.com/collections" data-analytics-event="{&quot;action&quot;:&quot;collections&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;open_source&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;collections_link_open_source_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty">Collections</span></a></li></ul></div></li></ul></div></div></li><li><div class="NavDropdown-module__container__l2YeI"><button type="button" class="NavDropdown-module__button__PEHWX" aria-expanded="false" aria-controls="_R_2nd_">Enterprise<svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-right NavDropdown-module__buttonIcon__Tkl8_" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m6.427 4.427 3.396 3.396a.25.25 0 0 1 0 .354l-3.396 3.396A.25.25 0 0 1 6 11.396V4.604a.25.25 0 0 1 .427-.177Z"></path></svg></button><div id="_R_2nd_" class="NavDropdown-module__dropdown__xm1jd"><ul class="NavDropdown-module__list__zuCgG"><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_5mnd_">ENTERPRISE SOLUTIONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_5mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise" data-analytics-event="{&quot;action&quot;:&quot;enterprise_platform&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;enterprise_platform_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-stack NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.122.392a1.75 1.75 0 0 1 1.756 0l5.003 2.902c.83.481.83 1.68 0 2.162L8.878 8.358a1.75 1.75 0 0 1-1.756 0L2.119 5.456a1.251 1.251 0 0 1 0-2.162ZM8.125 1.69a.248.248 0 0 0-.25 0l-4.63 2.685 4.63 2.685a.248.248 0 0 0 .25 0l4.63-2.685ZM1.601 7.789a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0L1.874 8.814A.75.75 0 0 1 1.6 7.789Zm0 3.5a.75.75 0 0 1 1.025-.273l5.249 3.044a.248.248 0 0 0 .25 0l5.249-3.044a.75.75 0 0 1 .752 1.298l-5.248 3.044a1.75 1.75 0 0 1-1.756 0l-5.248-3.044a.75.75 0 0 1-.273-1.025Z"></path></svg>Enterprise platform</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">AI-powered developer platform</span></span></a></li></ul></div></li><li><div class="NavGroup-module__group__W8SqJ"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--monospace___QXHDQ Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavGroup-module__title__Wzxz2" id="_R_9mnd_">AVAILABLE ADD-ONS</span><ul class="NavGroup-module__list__UCOFy" aria-labelledby="_R_9mnd_"><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/security/advanced-security" data-analytics-event="{&quot;action&quot;:&quot;github_advanced_security&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;github_advanced_security_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-shield-check NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m8.533.133 5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667l5.25-1.68a1.748 1.748 0 0 1 1.066 0Zm-.61 1.429.001.001-5.25 1.68a.251.251 0 0 0-.174.237V7c0 1.36.275 2.666 1.057 3.859.784 1.194 2.121 2.342 4.366 3.298a.196.196 0 0 0 .154 0c2.245-.957 3.582-2.103 4.366-3.297C13.225 9.666 13.5 8.358 13.5 7V3.48a.25.25 0 0 0-.174-.238l-5.25-1.68a.25.25 0 0 0-.153 0ZM11.28 6.28l-3.5 3.5a.75.75 0 0 1-1.06 0l-1.5-1.5a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l.97.97 2.97-2.97a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path></svg>GitHub Advanced Security</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade security features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/features/copilot/copilot-business" data-analytics-event="{&quot;action&quot;:&quot;copilot_for_business&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;copilot_for_business_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copilot NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.998 15.035c-4.562 0-7.873-2.914-7.998-3.749V9.338c.085-.628.677-1.686 1.588-2.065.013-.07.024-.143.036-.218.029-.183.06-.384.126-.612-.201-.508-.254-1.084-.254-1.656 0-.87.128-1.769.693-2.484.579-.733 1.494-1.124 2.724-1.261 1.206-.134 2.262.034 2.944.765.05.053.096.108.139.165.044-.057.094-.112.143-.165.682-.731 1.738-.899 2.944-.765 1.23.137 2.145.528 2.724 1.261.566.715.693 1.614.693 2.484 0 .572-.053 1.148-.254 1.656.066.228.098.429.126.612.012.076.024.148.037.218.924.385 1.522 1.471 1.591 2.095v1.872c0 .766-3.351 3.795-8.002 3.795Zm0-1.485c2.28 0 4.584-1.11 5.002-1.433V7.862l-.023-.116c-.49.21-1.075.291-1.727.291-1.146 0-2.059-.327-2.71-.991A3.222 3.222 0 0 1 8 6.303a3.24 3.24 0 0 1-.544.743c-.65.664-1.563.991-2.71.991-.652 0-1.236-.081-1.727-.291l-.023.116v4.255c.419.323 2.722 1.433 5.002 1.433ZM6.762 2.83c-.193-.206-.637-.413-1.682-.297-1.019.113-1.479.404-1.713.7-.247.312-.369.789-.369 1.554 0 .793.129 1.171.308 1.371.162.181.519.379 1.442.379.853 0 1.339-.235 1.638-.54.315-.322.527-.827.617-1.553.117-.935-.037-1.395-.241-1.614Zm4.155-.297c-1.044-.116-1.488.091-1.681.297-.204.219-.359.679-.242 1.614.091.726.303 1.231.618 1.553.299.305.784.54 1.638.54.922 0 1.28-.198 1.442-.379.179-.2.308-.578.308-1.371 0-.765-.123-1.242-.37-1.554-.233-.296-.693-.587-1.713-.7Z"></path><path d="M6.25 9.037a.75.75 0 0 1 .75.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 .75-.75Zm4.25.75v1.501a.75.75 0 0 1-1.5 0V9.787a.75.75 0 0 1 1.5 0Z"></path></svg>Copilot for Business</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade AI features</span></span></a></li><li><a class="Primer_Brand__Link-module__Link___lF11y Primer_Brand__Link-module__Link--default___VRVW0 NavLink-module__link__EG3d4" href="https://github.com/enterprise/premium-support" data-analytics-event="{&quot;action&quot;:&quot;premium_support&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;enterprise&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;premium_support_link_enterprise_navbar&quot;}"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Link-module__Link--label___jM8Ty"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS Primer_Brand__Text-module__Text--weight-medium___qJKf_ NavLink-module__title__Q7t0p"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-comment-discussion NavLink-module__icon__ltGNM" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M1.75 1h8.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 10.25 10H7.061l-2.574 2.573A1.458 1.458 0 0 1 2 11.543V10h-.25A1.75 1.75 0 0 1 0 8.25v-5.5C0 1.784.784 1 1.75 1ZM1.5 2.75v5.5c0 .138.112.25.25.25h1a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h3.5a.25.25 0 0 0 .25-.25v-5.5a.25.25 0 0 0-.25-.25h-8.5a.25.25 0 0 0-.25.25Zm13 2a.25.25 0 0 0-.25-.25h-.5a.75.75 0 0 1 0-1.5h.5c.966 0 1.75.784 1.75 1.75v5.5A1.75 1.75 0 0 1 14.25 12H14v1.543a1.458 1.458 0 0 1-2.487 1.03L9.22 12.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.22 2.22v-2.19a.75.75 0 0 1 .75-.75h1a.25.25 0 0 0 .25-.25Z"></path></svg>Premium Support</span><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--muted___rE6mh Primer_Brand__Text-module__Text--200____P1wy Primer_Brand__Text-module__Text--antialiased___TYoXS NavLink-module__subtitle__X4gkW">Enterprise-grade 24/7 support</span></span></a></li></ul></div></li></ul></div></div></li><li><a href="https://github.com/pricing" data-analytics-event="{&quot;action&quot;:&quot;pricing&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;pricing&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;pricing_link_pricing_navbar&quot;}" class="MarketingNavigation-module__navLink__hUomM">Pricing</a></li></ul></nav><div class="MarketingHeader-module__ctaContainer__tBmPz"><div class="HeaderSearch-module__searchSlot__oVOUS"><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderSearch-module__trigger__zsF9q" type="button" aria-haspopup="dialog" aria-expanded="false" aria-label="Search or jump to, type / to search" data-analytics-event="{&quot;action&quot;:&quot;searchbar&quot;,&quot;tag&quot;:&quot;input&quot;,&quot;context&quot;:&quot;global&quot;,&quot;location&quot;:&quot;navbar&quot;,&quot;label&quot;:&quot;searchbar_input_global_navbar&quot;}"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"><span class="HeaderSearch-module__content__kMpxU"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search HeaderSearch-module__icon__wcrHX" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg><span class="HeaderSearch-module__label__d1iWG">Search</span><kbd class="HeaderSearch-module__kbd__HNG0o" aria-hidden="true">/</kbd></span></span></span></button><div class="d-none"></div></div><div class="AuthCTAs-module__signInWrap__q2P60"><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq AuthCTAs-module__desktopActionGap__UZuXT AuthCTAs-module__hiddenBelowLg__BfKBw" href="/login?return_to=https%3A%2F%2Fgithub.com%2Ffirebase%2FFirebaseUI-Android%2Fblob%2Fmaster%2Fdatabase%2FREADME.md" data-analytics-event="{&quot;action&quot;:&quot;sign_in&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_in_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="16f0d2af3561e6cd5079dcb9462de78d2d4e89acf0e47ecf358da01a3700d0e2"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH">Sign in</span></span></a></div><a class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--secondary___gHnw_ Primer_Brand__Button-module__Button--size-small___zQrEw AuthCTAs-module__cta__WpwQq" href="/signup?ref_cta=Sign+up&amp;ref_loc=header+logged+out&amp;ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fblob%2Fshow&amp;source=header-repo&amp;source_repo=firebase%2FFirebaseUI-Android" data-analytics-event="{&quot;action&quot;:&quot;sign_up&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;context&quot;:&quot;auth_cta&quot;,&quot;location&quot;:&quot;header&quot;,&quot;label&quot;:&quot;sign_up_link_auth_cta_header&quot;}" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;site header menu&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;SIGN_UP&quot;,&quot;originating_url&quot;:&quot;https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="16f0d2af3561e6cd5079dcb9462de78d2d4e89acf0e47ecf358da01a3700d0e2"><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-secondary___eJ0_a">Sign up</span></span></a><button class="Primer_Brand__Button-module__Button___scH9Z Primer_Brand__Button-module__Button--subtle___F7pEE Primer_Brand__Button-module__Button--size-small___zQrEw HeaderAppearanceSettings-module__trigger__hUheK" type="button" aria-haspopup="dialog" aria-labelledby="_R_fbd_"><span class="Primer_Brand__Button-module__Button__leading-visual___jjtTe" data-testid="Button-leading-visual"><svg data-component="Octicon" focusable="false" aria-hidden="true" class="octicon octicon-sliders Primer_Brand__Button-module__Button__icon-visual____qybb" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M15 2.75a.75.75 0 0 1-.75.75h-4a.75.75 0 0 1 0-1.5h4a.75.75 0 0 1 .75.75Zm-8.5.75v1.25a.75.75 0 0 0 1.5 0v-4a.75.75 0 0 0-1.5 0V2H1.75a.75.75 0 0 0 0 1.5H6.5Zm1.25 5.25a.75.75 0 0 0 0-1.5h-6a.75.75 0 0 0 0 1.5h6ZM15 8a.75.75 0 0 1-.75.75H11.5V10a.75.75 0 1 1-1.5 0V6a.75.75 0 0 1 1.5 0v1.25h2.75A.75.75 0 0 1 15 8Zm-9 5.25v-2a.75.75 0 0 0-1.5 0v1.25H1.75a.75.75 0 0 0 0 1.5H4.5v1.25a.75.75 0 0 0 1.5 0v-2Zm9 0a.75.75 0 0 1-.75.75h-6a.75.75 0 0 1 0-1.5h6a.75.75 0 0 1 .75.75Z"></path></svg></span><span class="Primer_Brand__Button-module__Button__text___ED0bX"><span class="Primer_Brand__Text-module__Text___XeGJJ Primer_Brand__Text-module__Text-font--mona-sans___a8XJD Primer_Brand__Text-module__Text--default___GhPh_ Primer_Brand__Text-module__Text--100___B2ueX Primer_Brand__Text-module__Text--weight-medium___qJKf_ Primer_Brand__Button-module__Button--label___qrkyz Primer_Brand__Button-module__Button--label-subtle___8ndWH"></span></span></button><div class="Primer_Brand__Tooltip-module__Tooltip___0Eipx" data-direction="s" aria-hidden="true" id="_R_fbd_">Appearance settings</div></div></div></div></div><div class="MarketingHeader-module__bottomBorder__uZT38" aria-hidden="true"></div></header></div></div>
</react-partial>



      <div hidden="hidden" data-view-component="true" class="js-stale-session-flash stale-session-flash flash flash-warn flash-full">
  
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
        <span class="js-stale-session-flash-signed-in" hidden>You signed in with another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-signed-out" hidden>You signed out in another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>
        <span class="js-stale-session-flash-switched" hidden>You switched accounts on another tab or window. <a class="Link--inTextBlock" href="">Reload</a> to refresh your session.</span>

    <button id="icon-button-887adcaf-4e94-4fe1-a6b7-983901bd023f" aria-labelledby="tooltip-be2a868d-a57d-497a-9897-2746ed352f0b" type="button" data-view-component="true" class="Button Button--iconOnly Button--invisible Button--medium flash-close js-flash-close">  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x Button-visual">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
</button><tool-tip id="tooltip-be2a868d-a57d-497a-9897-2746ed352f0b" for="icon-button-887adcaf-4e94-4fe1-a6b7-983901bd023f" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Dismiss alert</tool-tip>


  
</div>
    </div>

  <div id="start-of-content" class="show-on-focus"></div>








    <div id="js-flash-container" class="flash-container" data-turbo-replace>





  <template class="js-flash-template">
    
<div class="flash flash-full   {{ className }}">
  <div >
    <button autofocus class="flash-close js-flash-close" type="button" aria-label="Dismiss this message">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    <div aria-atomic="true" role="alert" class="js-flash-alert">
      
      <div>{{ message }}</div>

    </div>
  </div>
</div>
  </template>
</div>


    






  <div
    class="application-main "
    data-commit-hovercards-enabled
    data-discussion-hovercards-enabled
    data-issue-and-pr-hovercards-enabled
    data-project-hovercards-enabled
  >
        <div itemscope itemtype="http://schema.org/SoftwareSourceCode" class="">
    <main id="js-repo-pjax-container" >
      
      
    

      <include-fragment src="/in-product-messaging/budget-threshold-banner?organization=firebase" data-nonce="v2:45a0a27a-909d-f88a-6773-57f2e6405273" data-view-component="true">
  
  <div data-show-on-forbidden-error hidden>
    <div class="Box">
  <div class="blankslate-container">
    <div data-view-component="true" class="blankslate blankslate-spacious color-bg-default rounded-2">
      

      <h3 data-view-component="true" class="blankslate-heading">        Uh oh!
</h3>
      <p data-view-component="true" class="blankslate-description">        <p class="color-fg-muted my-2 mb-2 ws-normal">There was an error while loading. <a class="Link--inTextBlock" data-turbo="false" href="" aria-label="Please reload this page">Please reload this page</a>.</p>
</p>

</div>  </div>
</div>  </div>
</include-fragment>

    








  

    <div id="repository-container-header"  class="tmp-pt-3 hide-full-screen" style="background-color: var(--page-header-bgColor, var(--color-page-header-bg));" data-turbo-replace>

        <div class="d-flex flex-nowrap flex-justify-end tmp-mb-3  tmp-px-3 tmp-px-lg-5" style="gap: 1rem;">

          <div class="flex-auto min-width-0 width-fit">
              
  <div class=" d-flex flex-wrap flex-items-center wb-break-word f3 text-normal">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo color-fg-muted mr-2 tmp-mr-2">
    <path d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"></path>
</svg>
    
    <span class="author flex-self-stretch" itemprop="author">
      <a class="url fn" rel="author" data-hovercard-type="organization" data-hovercard-url="/orgs/firebase/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/firebase">
        firebase
</a>    </span>
    <span class="mx-1 flex-self-stretch color-fg-muted">/</span>
    <strong itemprop="name" class="mr-2 flex-self-stretch">
      <a data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" href="/firebase/FirebaseUI-Android">FirebaseUI-Android</a>
    </strong>

    <span></span><span class="Label Label--secondary v-align-middle mr-1">Public</span>
  </div>


          </div>

          <div id="repository-details-container" class="flex-shrink-0" data-turbo-replace style="max-width: 70%;">
              <ul class="pagehead-actions flex-shrink-0 d-none d-md-inline" style="padding: 2px 0;">
    
      

  <li>
            <a href="/login?return_to=%2Ffirebase%2FFirebaseUI-Android" rel="nofollow" id="repository-details-watch-button" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;notification subscription menu watch&quot;,&quot;repository_id&quot;:null,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="533204b440877d65a08560e2cc5daab2092df374523b6647d322794acb5b97c7" aria-label="You must be signed in to change notification settings" data-view-component="true" class="btn-sm btn">    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-bell mr-2 tmp-mr-2">
    <path d="M8 16a2 2 0 0 0 1.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 0 0 8 16ZM3 5a5 5 0 0 1 10 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.519 1.519 0 0 1 13.482 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947Zm5-3.5A3.5 3.5 0 0 0 4.5 5v2.947c0 .346-.102.683-.294.97l-1.703 2.556a.017.017 0 0 0-.003.01l.001.006c0 .002.002.004.004.006l.006.004.007.001h10.964l.007-.001.006-.004.004-.006.001-.007a.017.017 0 0 0-.003-.01l-1.703-2.554a1.745 1.745 0 0 1-.294-.97V5A3.5 3.5 0 0 0 8 1.5Z"></path>
</svg>Notifications
</a>    <tool-tip id="tooltip-bc8b7a01-32cb-4a31-8566-8c79182c1546" for="repository-details-watch-button" popover="manual" data-direction="s" data-type="description" data-view-component="true" class="sr-only position-absolute">You must be signed in to change notification settings</tool-tip>

  </li>

  <li>
          <a icon="repo-forked" id="fork-button" href="/login?return_to=%2Ffirebase%2FFirebaseUI-Android" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;repo details fork button&quot;,&quot;repository_id&quot;:38835213,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="399920baecf3e6215fe947e8ccdca507559bdd97214ee6f2de108b3c6e180e24" data-view-component="true" class="btn-sm btn">    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-repo-forked mr-2 tmp-mr-2">
    <path d="M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z"></path>
</svg>Fork
    <span id="repo-network-counter" data-pjax-replace="true" data-turbo-replace="true" title="1,869" data-view-component="true" class="Counter">1.9k</span>
</a>
  </li>

  <li>
        <div data-view-component="true" class="BtnGroup d-flex">
        <a href="/login?return_to=%2Ffirebase%2FFirebaseUI-Android" rel="nofollow" data-hydro-click="{&quot;event_type&quot;:&quot;authentication.click&quot;,&quot;payload&quot;:{&quot;location_in_page&quot;:&quot;star button&quot;,&quot;repository_id&quot;:38835213,&quot;auth_type&quot;:&quot;LOG_IN&quot;,&quot;originating_url&quot;:&quot;https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md&quot;,&quot;user_id&quot;:null}}" data-hydro-click-hmac="4a14c238345978a2c77fa599a8b0fc914d1df63d7dc1d56fedfee0fd5708e2ee" aria-label="You must be signed in to star a repository" data-view-component="true" class="tooltipped tooltipped-sw btn-sm btn">    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-star v-align-text-bottom d-inline-block mr-2 tmp-mr-2">
    <path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path>
</svg><span data-view-component="true" class="d-inline">
          Star
</span>          <span id="repo-stars-counter-star" aria-label="4804 users starred this repository" data-singular-suffix="user starred this repository" data-plural-suffix="users starred this repository" data-turbo-replace="true" title="4,804" data-view-component="true" class="Counter js-social-count">4.8k</span>
</a></div>
  </li>

</ul>

          </div>
        </div>

          <div id="responsive-meta-container" data-turbo-replace>
</div>


            <nav data-pjax="#js-repo-pjax-container" aria-label="Repository" data-view-component="true" class="js-repo-nav js-sidenav-container-pjax js-responsive-underlinenav overflow-hidden UnderlineNav px-3 tmp-px-3 px-md-4 tmp-px-md-4 px-lg-5 tmp-px-lg-5">

  <ul data-view-component="true" class="UnderlineNav-body list-style-none">
      <li data-view-component="true" class="d-inline-flex">
  <a id="code-tab" href="/firebase/FirebaseUI-Android" data-tab-item="i0code-tab" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches repo_packages repo_deployments repo_attestations /firebase/FirebaseUI-Android" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g c" data-command-id="repositories:go-to-code" data-react-nav="code-view" data-react-nav-anchor="code-view-repo-link" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Code&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" aria-current="page" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item selected">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code UnderlineNav-octicon d-none d-sm-inline">
    <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
</svg>
        <span data-content="Code">Code</span>
          <span id="code-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="issues-tab" href="/firebase/FirebaseUI-Android/issues" data-tab-item="i1issues-tab" data-selected-links="repo_issues repo_labels repo_milestones /firebase/FirebaseUI-Android/issues" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g i" data-command-id="repositories:go-to-issues" data-react-nav="issues-react" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Issues&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened UnderlineNav-octicon d-none d-sm-inline">
    <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path>
</svg>
        <span data-content="Issues">Issues</span>
          <span id="issues-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="2" data-view-component="true" class="Counter">2</span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="pull-requests-tab" href="/firebase/FirebaseUI-Android/pulls" data-tab-item="i2pull-requests-tab" data-selected-links="repo_pulls checks /firebase/FirebaseUI-Android/pulls" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g p" data-command-id="repositories:go-to-pull-requests" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Pull requests&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request UnderlineNav-octicon d-none d-sm-inline">
    <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path>
</svg>
        <span data-content="Pull requests">Pull requests</span>
          <span id="pull-requests-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="12" data-view-component="true" class="Counter">12</span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="actions-tab" href="/firebase/FirebaseUI-Android/actions" data-tab-item="i3actions-tab" data-selected-links="repo_actions /firebase/FirebaseUI-Android/actions" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g a" data-command-id="repositories:go-to-actions" data-react-nav="actions-workflows" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Actions&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play UnderlineNav-octicon d-none d-sm-inline">
    <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path>
</svg>
        <span data-content="Actions">Actions</span>
          <span id="actions-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="projects-tab" href="/firebase/FirebaseUI-Android/projects" data-tab-item="i4projects-tab" data-selected-links="repo_projects new_repo_project repo_project /firebase/FirebaseUI-Android/projects" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g b" data-command-id="repositories:go-to-projects" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Projects&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table UnderlineNav-octicon d-none d-sm-inline">
    <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path>
</svg>
        <span data-content="Projects">Projects</span>
          <span id="projects-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="security-and-quality-tab" href="/firebase/FirebaseUI-Android/security" data-tab-item="i5security-and-quality-tab" data-selected-links="security overview alerts policy token_scanning code_scanning /firebase/FirebaseUI-Android/security" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-hotkey="g s" data-command-id="repositories:go-to-security" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Security and quality&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield UnderlineNav-octicon d-none d-sm-inline">
    <path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
        <span data-content="Security and quality">Security and quality</span>
          <span id="security-and-quality-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="0" hidden="hidden" data-view-component="true" class="Counter">0</span>


    
</a></li>
      <li data-view-component="true" class="d-inline-flex">
  <a id="insights-tab" href="/firebase/FirebaseUI-Android/pulse" data-tab-item="i6insights-tab" data-selected-links="repo_graphs repo_contributors dependency_graph dependabot_updates pulse people community /firebase/FirebaseUI-Android/pulse" data-pjax="#repo-content-pjax-container" data-turbo-frame="repo-content-turbo-frame" data-command-id="repositories:go-to-insights" data-analytics-event="{&quot;category&quot;:&quot;Underline navbar&quot;,&quot;action&quot;:&quot;Click tab&quot;,&quot;label&quot;:&quot;Insights&quot;,&quot;target&quot;:&quot;UNDERLINE_NAV.TAB&quot;}" data-view-component="true" class="UnderlineNav-item no-wrap js-responsive-underlinenav-item js-selected-navigation-item">
    
              <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph UnderlineNav-octicon d-none d-sm-inline">
    <path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
        <span data-content="Insights">Insights</span>
          <span id="insights-repo-tab-count" data-pjax-replace="" data-turbo-replace="" title="Not available" data-view-component="true" class="Counter"></span>


    
</a></li>
</ul>
    <div style="visibility:hidden;" data-view-component="true" class="UnderlineNav-actions js-responsive-underlinenav-overflow position-absolute pr-3 tmp-pr-3 pr-md-4 tmp-pr-md-4 pr-lg-5 tmp-pr-lg-5 right-0">      <action-menu data-select-variant="none" data-view-component="true">
  <focus-group direction="vertical" mnemonics retain>
    <button id="action-menu-87c4e375-a6bd-4416-bcda-ad866af89397-button" popovertarget="action-menu-87c4e375-a6bd-4416-bcda-ad866af89397-overlay" aria-controls="action-menu-87c4e375-a6bd-4416-bcda-ad866af89397-list" aria-haspopup="true" aria-labelledby="tooltip-9cb7510e-2b35-4235-b94a-c81dc6f0e7ea" type="button" data-view-component="true" class="Button Button--iconOnly Button--secondary Button--medium UnderlineNav-item">  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-kebab-horizontal Button-visual">
    <path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path>
</svg>
</button><tool-tip id="tooltip-9cb7510e-2b35-4235-b94a-c81dc6f0e7ea" for="action-menu-87c4e375-a6bd-4416-bcda-ad866af89397-button" popover="manual" data-direction="s" data-type="label" data-view-component="true" class="sr-only position-absolute">Additional navigation options</tool-tip>


<anchored-position data-target="action-menu.overlay" id="action-menu-87c4e375-a6bd-4416-bcda-ad866af89397-overlay" anchor="action-menu-87c4e375-a6bd-4416-bcda-ad866af89397-button" align="start" side="outside-bottom" anchor-offset="normal" popover="auto" data-view-component="true">
  <div data-view-component="true" class="Overlay Overlay--size-auto">
    
      <div data-view-component="true" class="Overlay-body Overlay-body--paddingNone">          <action-list>
  <div data-view-component="true">
    <ul aria-labelledby="action-menu-87c4e375-a6bd-4416-bcda-ad866af89397-button" id="action-menu-87c4e375-a6bd-4416-bcda-ad866af89397-list" role="menu" data-view-component="true" class="ActionListWrap--inset ActionListWrap">
        <li hidden="hidden" data-menu-item="i0code-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-22e17973-360a-472d-8c97-403d5d23addd" href="/firebase/FirebaseUI-Android" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-code">
    <path d="m11.28 3.22 4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L13.94 8l-3.72-3.72a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215Zm-6.56 0a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L2.06 8l3.72 3.72a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L.47 8.53a.75.75 0 0 1 0-1.06Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Code
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i1issues-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-88736222-759a-48fb-ad3a-d44ef0f86509" href="/firebase/FirebaseUI-Android/issues" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-issue-opened">
    <path d="M8 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path><path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Issues
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i2pull-requests-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-c2e72591-5c26-4fe5-a966-937f352c3c74" href="/firebase/FirebaseUI-Android/pulls" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-git-pull-request">
    <path d="M1.5 3.25a2.25 2.25 0 1 1 3 2.122v5.256a2.251 2.251 0 1 1-1.5 0V5.372A2.25 2.25 0 0 1 1.5 3.25Zm5.677-.177L9.573.677A.25.25 0 0 1 10 .854V2.5h1A2.5 2.5 0 0 1 13.5 5v5.628a2.251 2.251 0 1 1-1.5 0V5a1 1 0 0 0-1-1h-1v1.646a.25.25 0 0 1-.427.177L7.177 3.427a.25.25 0 0 1 0-.354ZM3.75 2.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm0 9.5a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Zm8.25.75a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Pull requests
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i3actions-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-3aaf3f33-2d9b-453c-a8ab-b25571530691" href="/firebase/FirebaseUI-Android/actions" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-play">
    <path d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0ZM1.5 8a6.5 6.5 0 1 0 13 0 6.5 6.5 0 0 0-13 0Zm4.879-2.773 4.264 2.559a.25.25 0 0 1 0 .428l-4.264 2.559A.25.25 0 0 1 6 10.559V5.442a.25.25 0 0 1 .379-.215Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Actions
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i4projects-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-c5ab1061-821e-44f8-9bd7-992cf51b6366" href="/firebase/FirebaseUI-Android/projects" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-table">
    <path d="M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25ZM6.5 6.5v8h7.75a.25.25 0 0 0 .25-.25V6.5Zm8-1.5V1.75a.25.25 0 0 0-.25-.25H6.5V5Zm-13 1.5v7.75c0 .138.112.25.25.25H5v-8ZM5 5V1.5H1.75a.25.25 0 0 0-.25.25V5Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Projects
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i5security-and-quality-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-e1c138cb-edcf-4cc5-ab94-1aa86bca442d" href="/firebase/FirebaseUI-Android/security" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-shield">
    <path d="M7.467.133a1.748 1.748 0 0 1 1.066 0l5.25 1.68A1.75 1.75 0 0 1 15 3.48V7c0 1.566-.32 3.182-1.303 4.682-.983 1.498-2.585 2.813-5.032 3.855a1.697 1.697 0 0 1-1.33 0c-2.447-1.042-4.049-2.357-5.032-3.855C1.32 10.182 1 8.566 1 7V3.48a1.75 1.75 0 0 1 1.217-1.667Zm.61 1.429a.25.25 0 0 0-.153 0l-5.25 1.68a.25.25 0 0 0-.174.238V7c0 1.358.275 2.666 1.057 3.86.784 1.194 2.121 2.34 4.366 3.297a.196.196 0 0 0 .154 0c2.245-.956 3.582-2.104 4.366-3.298C13.225 9.666 13.5 8.36 13.5 7V3.48a.251.251 0 0 0-.174-.237l-5.25-1.68ZM8.75 4.75v3a.75.75 0 0 1-1.5 0v-3a.75.75 0 0 1 1.5 0ZM9 10.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Security and quality
</span>      
</a>
  
</li>
        <li hidden="hidden" data-menu-item="i6insights-tab" data-targets="action-list.items" role="none" data-view-component="true" class="ActionListItem">
    
    
    <a tabindex="-1" id="item-02f73495-90f0-409a-b904-e1166ebd9040" href="/firebase/FirebaseUI-Android/pulse" role="menuitem" data-view-component="true" class="ActionListContent ActionListContent--visual16">
        <span class="ActionListItem-visual ActionListItem-visual--leading">
          <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-graph">
    <path d="M1.5 1.75V13.5h13.75a.75.75 0 0 1 0 1.5H.75a.75.75 0 0 1-.75-.75V1.75a.75.75 0 0 1 1.5 0Zm14.28 2.53-5.25 5.25a.75.75 0 0 1-1.06 0L7 7.06 4.28 9.78a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042l3.25-3.25a.75.75 0 0 1 1.06 0L10 7.94l4.72-4.72a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042Z"></path>
</svg>
        </span>
      
        <span data-view-component="true" class="ActionListItem-label">
          Insights
</span>      
</a>
  
</li>
</ul>    
</div></action-list>


</div>
      
</div></anchored-position>  </focus-group>
</action-menu></div>
</nav>

    </div>
  



<turbo-frame id="repo-content-turbo-frame" target="_top" data-turbo-action="advance" class="">
    <div id="repo-content-pjax-container" class="repository-content " >
    



    
      
    








<react-app
  app-name="code-view"
  initial-path="/firebase/FirebaseUI-Android/blob/master/database/README.md"
  style="display: block; min-height: calc(100vh - 64px);"
  data-attempted-ssr="true"
  data-ssr="true"
  data-lazy="false"
  data-alternate="false"
  data-data-router-enabled="true"
  data-react-profiling="false"
>
  
  <script type="application/json" data-target="react-app.embeddedData">{"payload":{"codeViewBlobRoute":{"csv":null,"csvError":null,"headerInfo":{"toc":[{"level":1,"text":"FirebaseUI for Realtime Database","anchor":"firebaseui-for-realtime-database","htmlText":"FirebaseUI for Realtime Database"},{"level":2,"text":"Table of contents","anchor":"table-of-contents","htmlText":"Table of contents"},{"level":2,"text":"Data model","anchor":"data-model","htmlText":"Data model"},{"level":3,"text":"Querying","anchor":"querying","htmlText":"Querying"},{"level":2,"text":"Using FirebaseUI to populate a RecyclerView","anchor":"using-firebaseui-to-populate-a-recyclerview","htmlText":"Using FirebaseUI to populate a RecyclerView"},{"level":3,"text":"Choosing an adapter","anchor":"choosing-an-adapter","htmlText":"Choosing an adapter"},{"level":3,"text":"Using the FirebaseRecyclerAdapter","anchor":"using-the-firebaserecycleradapter","htmlText":"Using the FirebaseRecyclerAdapter"},{"level":4,"text":"FirebaseRecyclerAdapter lifecycle","anchor":"firebaserecycleradapter-lifecycle","htmlText":"FirebaseRecyclerAdapter lifecycle"},{"level":5,"text":"Start/stop listening","anchor":"startstop-listening","htmlText":"Start/stop listening"},{"level":5,"text":"Automatic listening","anchor":"automatic-listening","htmlText":"Automatic listening"},{"level":4,"text":"Data and error events","anchor":"data-and-error-events","htmlText":"Data and error events"},{"level":3,"text":"Using the FirebaseRecyclerPagingAdapter","anchor":"using-the-firebaserecyclerpagingadapter","htmlText":"Using the FirebaseRecyclerPagingAdapter"},{"level":4,"text":"FirebaseRecyclerPagingAdapter lifecycle","anchor":"firebaserecyclerpagingadapter-lifecycle","htmlText":"FirebaseRecyclerPagingAdapter lifecycle"},{"level":5,"text":"Start/stop listening","anchor":"startstop-listening-1","htmlText":"Start/stop listening"},{"level":5,"text":"Automatic listening","anchor":"automatic-listening-1","htmlText":"Automatic listening"},{"level":4,"text":"Paging events","anchor":"paging-events","htmlText":"Paging events"},{"level":5,"text":"In Java","anchor":"in-java","htmlText":"In Java"},{"level":4,"text":"In Kotlin","anchor":"in-kotlin","htmlText":"In Kotlin"},{"level":2,"text":"Using FirebaseUI to populate a ListView","anchor":"using-firebaseui-to-populate-a-listview","htmlText":"Using FirebaseUI to populate a ListView"},{"level":2,"text":"Using FirebaseUI with indexed data","anchor":"using-firebaseui-with-indexed-data","htmlText":"Using FirebaseUI with indexed data"},{"level":3,"text":"A note on ordering","anchor":"a-note-on-ordering","htmlText":"A note on ordering"}]},"issueTemplate":null,"discussionTemplate":null,"richText":"\u003carticle class=\"markdown-body entry-content container-lg\" itemprop=\"text\"\u003e\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFirebaseUI for Realtime Database\u003c/h1\u003e\u003ca id=\"user-content-firebaseui-for-realtime-database\" class=\"anchor\" aria-label=\"Permalink: FirebaseUI for Realtime Database\" href=\"#firebaseui-for-realtime-database\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFirebaseUI makes it simple to bind data from the Firebase Realtime Database to your app's UI.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eBefore using this library, you should be familiar with the following topics:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"https://firebase.google.com/docs/database/android/lists-of-data\" rel=\"nofollow\"\u003eWorking with lists of data in Firebase Realtime Database\u003c/a\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView\" rel=\"nofollow\"\u003eDisplaying lists of data using a RecyclerView\u003c/a\u003e.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eTable of contents\u003c/h2\u003e\u003ca id=\"user-content-table-of-contents\" class=\"anchor\" aria-label=\"Permalink: Table of contents\" href=\"#table-of-contents\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#data-model\"\u003eData model\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#querying\"\u003eQuerying\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#using-firebaseui-to-populate-a-recyclerview\"\u003ePopulating a RecyclerView\u003c/a\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#using-the-firebaserecycleradapter\"\u003eUsing the FirebaseRecyclerAdapter\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#using-the-firebaserecyclerpagingadapter\"\u003eUsing the FirebaseRecyclerPagingAdapter\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#using-firebaseui-to-populate-a-listview\"\u003ePopulating a ListView\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#using-firebaseui-with-indexed-data\"\u003eHandling indexed data\u003c/a\u003e\n\u003col dir=\"auto\"\u003e\n\u003cli\u003e\u003ca href=\"#a-note-on-ordering\"\u003eWarnings\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eData model\u003c/h2\u003e\u003ca id=\"user-content-data-model\" class=\"anchor\" aria-label=\"Permalink: Data model\" href=\"#data-model\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eImagine you have a chat app where each chat message is an item in the \u003ccode\u003echats\u003c/code\u003e node\nof your database. In your app, you may represent a chat message like this:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"public class Chat {\n    private String mName;\n    private String mMessage;\n    private String mUid;\n\n    public Chat() {}  // Needed for Firebase\n\n    public Chat(String name, String message, String uid) {\n        mName = name;\n        mMessage = message;\n        mUid = uid;\n    }\n\n    public String getName() { return mName; }\n\n    public void setName(String name) { mName = name; }\n\n    public String getMessage() { return mMessage; }\n\n    public void setMessage(String message) { mMessage = message; }\n\n    public String getUid() { return mUid; }\n\n    public void setUid(String uid) { mUid = uid; }\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e {\n    \u003cspan class=\"pl-k\"\u003eprivate\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emName\u003c/span\u003e;\n    \u003cspan class=\"pl-k\"\u003eprivate\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emMessage\u003c/span\u003e;\n    \u003cspan class=\"pl-k\"\u003eprivate\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emUid\u003c/span\u003e;\n\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e() {}  \u003cspan class=\"pl-c\"\u003e// Needed for Firebase\u003c/span\u003e\n\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emessage\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003euid\u003c/span\u003e) {\n        \u003cspan class=\"pl-s1\"\u003emName\u003c/span\u003e = \u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e;\n        \u003cspan class=\"pl-s1\"\u003emMessage\u003c/span\u003e = \u003cspan class=\"pl-s1\"\u003emessage\u003c/span\u003e;\n        \u003cspan class=\"pl-s1\"\u003emUid\u003c/span\u003e = \u003cspan class=\"pl-s1\"\u003euid\u003c/span\u003e;\n    }\n\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-en\"\u003egetName\u003c/span\u003e() { \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emName\u003c/span\u003e; }\n\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003esetName\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e) { \u003cspan class=\"pl-s1\"\u003emName\u003c/span\u003e = \u003cspan class=\"pl-s1\"\u003ename\u003c/span\u003e; }\n\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-en\"\u003egetMessage\u003c/span\u003e() { \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emMessage\u003c/span\u003e; }\n\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003esetMessage\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emessage\u003c/span\u003e) { \u003cspan class=\"pl-s1\"\u003emMessage\u003c/span\u003e = \u003cspan class=\"pl-s1\"\u003emessage\u003c/span\u003e; }\n\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-en\"\u003egetUid\u003c/span\u003e() { \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emUid\u003c/span\u003e; }\n\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003esetUid\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003euid\u003c/span\u003e) { \u003cspan class=\"pl-s1\"\u003emUid\u003c/span\u003e = \u003cspan class=\"pl-s1\"\u003euid\u003c/span\u003e; }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eA few things to note about this model class:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003eThe getters and setters follow the JavaBean naming pattern which allows Firebase to map\nthe data to field names (ex: \u003ccode\u003egetName()\u003c/code\u003e provides the \u003ccode\u003ename\u003c/code\u003e field).\u003c/li\u003e\n\u003cli\u003eThe class has an empty constructor, which is required for Firebase's automatic data mapping.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp dir=\"auto\"\u003eFor a properly constructed model class like the \u003ccode\u003eChat\u003c/code\u003e class above, Firebase can perform automatic\nserialization in \u003ccode\u003eDatabaseReference#setValue()\u003c/code\u003e and automatic deserialization in\n\u003ccode\u003eDataSnapshot#getValue()\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eQuerying\u003c/h3\u003e\u003ca id=\"user-content-querying\" class=\"anchor\" aria-label=\"Permalink: Querying\" href=\"#querying\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eOn the main screen of your app, you may want to show the 50 most recent chat messages. With Firebase\nyou would use the following query:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"Query query = FirebaseDatabase.getInstance()\n        .getReference()\n        .child(\u0026quot;chats\u0026quot;)\n        .limitToLast(50);\"\u003e\u003cpre\u003e\u003cspan class=\"pl-smi\"\u003eQuery\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003equery\u003c/span\u003e = \u003cspan class=\"pl-smi\"\u003eFirebaseDatabase\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003egetInstance\u003c/span\u003e()\n        .\u003cspan class=\"pl-en\"\u003egetReference\u003c/span\u003e()\n        .\u003cspan class=\"pl-en\"\u003echild\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"chats\"\u003c/span\u003e)\n        .\u003cspan class=\"pl-en\"\u003elimitToLast\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e50\u003c/span\u003e);\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eTo retrieve this data without FirebaseUI, you might use \u003ccode\u003eaddChildEventListener\u003c/code\u003e to listen for\nlive updates:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"ChildEventListener childEventListener = new ChildEventListener() {\n    @Override\n    public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {\n        // ...\n    }\n\n    @Override\n    public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {\n        // ...\n    }\n\n    @Override\n    public void onChildRemoved(DataSnapshot dataSnapshot) {\n        // ...\n    }\n\n    @Override\n    public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {\n        // ...\n    }\n\n    @Override\n    public void onCancelled(DatabaseError databaseError) {\n        // ...\n    }\n};\nquery.addChildEventListener(childEventListener);\"\u003e\u003cpre\u003e\u003cspan class=\"pl-smi\"\u003eChildEventListener\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003echildEventListener\u003c/span\u003e = \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eChildEventListener\u003c/span\u003e() {\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonChildAdded\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eDataSnapshot\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edataSnapshot\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epreviousChildName\u003c/span\u003e) {\n        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n    }\n\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonChildChanged\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eDataSnapshot\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edataSnapshot\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epreviousChildName\u003c/span\u003e) {\n        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n    }\n\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonChildRemoved\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eDataSnapshot\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edataSnapshot\u003c/span\u003e) {\n        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n    }\n\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonChildMoved\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eDataSnapshot\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edataSnapshot\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eString\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epreviousChildName\u003c/span\u003e) {\n        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n    }\n\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonCancelled\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eDatabaseError\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003edatabaseError\u003c/span\u003e) {\n        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n    }\n};\n\u003cspan class=\"pl-s1\"\u003equery\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eaddChildEventListener\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003echildEventListener\u003c/span\u003e);\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUsing FirebaseUI to populate a \u003ccode\u003eRecyclerView\u003c/code\u003e\u003c/h2\u003e\u003ca id=\"user-content-using-firebaseui-to-populate-a-recyclerview\" class=\"anchor\" aria-label=\"Permalink: Using FirebaseUI to populate a RecyclerView\" href=\"#using-firebaseui-to-populate-a-recyclerview\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you're displaying a list of data, you likely want to bind the \u003ccode\u003eChat\u003c/code\u003e objects to a \u003ccode\u003eRecyclerView\u003c/code\u003e.\nThis means implementing a custom \u003ccode\u003eRecyclerView.Adapter\u003c/code\u003e and coordinating updates with the\n\u003ccode\u003eChildEventListener\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFear not, FirebaseUI does all of this for you automatically!\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eChoosing an adapter\u003c/h3\u003e\u003ca id=\"user-content-choosing-an-adapter\" class=\"anchor\" aria-label=\"Permalink: Choosing an adapter\" href=\"#choosing-an-adapter\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFirebaseUI offers two types of RecyclerView adapters for the Realtime Database:\u003c/p\u003e\n\u003cul dir=\"auto\"\u003e\n\u003cli\u003e\u003ccode\u003eFirebaseRecyclerAdapter\u003c/code\u003e — binds a \u003ccode\u003eQuery\u003c/code\u003e to a \u003ccode\u003eRecyclerView\u003c/code\u003e and responds to all real-time\nevents included items being added, removed, moved, or changed. Best used with small result sets\nsince all results are loaded at once.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eFirebaseRecyclerPagingAdapter\u003c/code\u003e — binds a \u003ccode\u003eQuery\u003c/code\u003e to a \u003ccode\u003eRecyclerView\u003c/code\u003e by loading data in pages. Best\nused with large, static data sets. Real-time events are not respected by this adapter, so it\nwill not detect new/removed items or changes to items already loaded.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUsing the FirebaseRecyclerAdapter\u003c/h3\u003e\u003ca id=\"user-content-using-the-firebaserecycleradapter\" class=\"anchor\" aria-label=\"Permalink: Using the FirebaseRecyclerAdapter\" href=\"#using-the-firebaserecycleradapter\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eFirebaseRecyclerAdapter\u003c/code\u003e binds a \u003ccode\u003eQuery\u003c/code\u003e to a \u003ccode\u003eRecyclerView\u003c/code\u003e. When data is added, removed,\nor changed these updates are automatically applied to your UI in real time.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eFirst, configure the adapter by building \u003ccode\u003eFirebaseRecyclerOptions\u003c/code\u003e. In this case we will continue\nwith our chat example:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\" FirebaseRecyclerOptions\u0026lt;Chat\u0026gt; options =\n                new FirebaseRecyclerOptions.Builder\u0026lt;Chat\u0026gt;()\n                        .setQuery(query, Chat.class)\n                        .build();\"\u003e\u003cpre\u003e \u003cspan class=\"pl-smi\"\u003eFirebaseRecyclerOptions\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e\u0026gt; \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e =\n                \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eFirebaseRecyclerOptions\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eBuilder\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e\u0026gt;()\n                        .\u003cspan class=\"pl-en\"\u003esetQuery\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003equery\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e.\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e)\n                        .\u003cspan class=\"pl-en\"\u003ebuild\u003c/span\u003e();\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you need to customize how your model class is parsed, you can use a custom \u003ccode\u003eSnapshotParser\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"...setQuery(..., new SnapshotParser\u0026lt;Chat\u0026gt;() {\n    @NonNull\n    @Override\n    public Chat parseSnapshot(@NonNull DataSnapshot snapshot) {\n        return ...;\n    }\n});\"\u003e\u003cpre\u003e...\u003cspan class=\"pl-en\"\u003esetQuery\u003c/span\u003e(..., \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eSnapshotParser\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e\u0026gt;() {\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eNonNull\u003c/span\u003e\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eparseSnapshot\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eNonNull\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eDataSnapshot\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esnapshot\u003c/span\u003e) {\n        \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e ...;\n    }\n});\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eNext create the \u003ccode\u003eFirebaseRecyclerAdapter\u003c/code\u003e object. You should already have a \u003ccode\u003eViewHolder\u003c/code\u003e subclass\nfor displaying each item. In this case we will use a custom \u003ccode\u003eChatHolder\u003c/code\u003e class:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter\u0026lt;Chat, ChatHolder\u0026gt;(options) {\n    @Override\n    public ChatHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n        // Create a new instance of the ViewHolder, in this case we are using a custom\n        // layout called R.layout.message for each item\n        View view = LayoutInflater.from(parent.getContext())\n                .inflate(R.layout.message, parent, false);\n\n        return new ChatHolder(view);\n    }\n\n    @Override\n    protected void onBindViewHolder(ChatHolder holder, int position, Chat model) {\n        // Bind the Chat object to the ChatHolder\n        // ...\n    }\n};\"\u003e\u003cpre\u003e\u003cspan class=\"pl-smi\"\u003eFirebaseRecyclerAdapter\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eadapter\u003c/span\u003e = \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eFirebaseRecyclerAdapter\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eChatHolder\u003c/span\u003e\u0026gt;(\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e) {\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eChatHolder\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonCreateViewHolder\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eViewGroup\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eparent\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eint\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eviewType\u003c/span\u003e) {\n        \u003cspan class=\"pl-c\"\u003e// Create a new instance of the ViewHolder, in this case we are using a custom\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e// layout called R.layout.message for each item\u003c/span\u003e\n        \u003cspan class=\"pl-smi\"\u003eView\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e = \u003cspan class=\"pl-smi\"\u003eLayoutInflater\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003efrom\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eparent\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003egetContext\u003c/span\u003e())\n                .\u003cspan class=\"pl-en\"\u003einflate\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eR\u003c/span\u003e.\u003cspan class=\"pl-s1\"\u003elayout\u003c/span\u003e.\u003cspan class=\"pl-s1\"\u003emessage\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eparent\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e);\n\n        \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eChatHolder\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003eview\u003c/span\u003e);\n    }\n\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eprotected\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonBindViewHolder\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eChatHolder\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eholder\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eint\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eposition\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emodel\u003c/span\u003e) {\n        \u003cspan class=\"pl-c\"\u003e// Bind the Chat object to the ChatHolder\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n    }\n};\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFinally attach the adapter to your \u003ccode\u003eRecyclerView\u003c/code\u003e with the \u003ccode\u003eRecyclerView#setAdapter()\u003c/code\u003e method.\nDon't forget to also set a \u003ccode\u003eLayoutManager\u003c/code\u003e!\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eFirebaseRecyclerAdapter lifecycle\u003c/h4\u003e\u003ca id=\"user-content-firebaserecycleradapter-lifecycle\" class=\"anchor\" aria-label=\"Permalink: FirebaseRecyclerAdapter lifecycle\" href=\"#firebaserecycleradapter-lifecycle\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eStart/stop listening\u003c/h5\u003e\u003ca id=\"user-content-startstop-listening\" class=\"anchor\" aria-label=\"Permalink: Start/stop listening\" href=\"#startstop-listening\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eFirebaseRecyclerAdapter\u003c/code\u003e uses an event listener to monitor changes to the Firebase query.\nTo begin listening for data, call the \u003ccode\u003estartListening()\u003c/code\u003e method. You may want to call this in your\n\u003ccode\u003eonStart()\u003c/code\u003e method. Make sure you have finished any authentication necessary to read the data\nbefore calling \u003ccode\u003estartListening()\u003c/code\u003e or your query will fail.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"@Override\nprotected void onStart() {\n    super.onStart();\n    adapter.startListening();\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eprotected\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonStart\u003c/span\u003e() {\n    \u003cspan class=\"pl-en\"\u003esuper\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eonStart\u003c/span\u003e();\n    \u003cspan class=\"pl-s1\"\u003eadapter\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003estartListening\u003c/span\u003e();\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSimilarly, the \u003ccode\u003estopListening()\u003c/code\u003e call removes the event  listener and all data in the adapter.\nCall this method when the containing Activity or Fragment stops:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"@Override\nprotected void onStop() {\n    super.onStop();\n    adapter.stopListening();\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eprotected\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonStop\u003c/span\u003e() {\n    \u003cspan class=\"pl-en\"\u003esuper\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eonStop\u003c/span\u003e();\n    \u003cspan class=\"pl-s1\"\u003eadapter\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003estopListening\u003c/span\u003e();\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAutomatic listening\u003c/h5\u003e\u003ca id=\"user-content-automatic-listening\" class=\"anchor\" aria-label=\"Permalink: Automatic listening\" href=\"#automatic-listening\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you don't want to manually start/stop listening you can use\n\u003ca href=\"https://developer.android.com/topic/libraries/architecture/index.html\" rel=\"nofollow\"\u003eAndroid Architecture Components\u003c/a\u003e to automatically manage the lifecycle of the\n\u003ccode\u003eFirebaseRecyclerAdapter\u003c/code\u003e. Pass a \u003ccode\u003eLifecycleOwner\u003c/code\u003e to\n\u003ccode\u003eFirebaseRecyclerOptions.Builder#setLifecycleOwner(...)\u003c/code\u003e and FirebaseUI will automatically\nstart and stop listening in \u003ccode\u003eonStart()\u003c/code\u003e and \u003ccode\u003eonStop()\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eData and error events\u003c/h4\u003e\u003ca id=\"user-content-data-and-error-events\" class=\"anchor\" aria-label=\"Permalink: Data and error events\" href=\"#data-and-error-events\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen using the \u003ccode\u003eFirebaseRecyclerAdapter\u003c/code\u003e you may want to perform some action every time data\nchanges or when there is an error. To do this, override the \u003ccode\u003eonDataChanged()\u003c/code\u003e and \u003ccode\u003eonError()\u003c/code\u003e\nmethods of the adapter:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter\u0026lt;Chat, ChatHolder\u0026gt;(options) {\n    // ...\n\n    @Override\n    public void onDataChanged() {\n        // Called each time there is a new data snapshot. You may want to use this method\n        // to hide a loading spinner or check for the \u0026quot;no documents\u0026quot; state and update your UI.\n        // ...\n    }\n\n    @Override\n    public void onError(DatabaseError e) {\n        // Called when there is an error getting data. You may want to update\n        // your UI to display an error message to the user.\n        // ...\n    }\n};\"\u003e\u003cpre\u003e\u003cspan class=\"pl-smi\"\u003eFirebaseRecyclerAdapter\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eadapter\u003c/span\u003e = \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eFirebaseRecyclerAdapter\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eChatHolder\u003c/span\u003e\u0026gt;(\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e) {\n    \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonDataChanged\u003c/span\u003e() {\n        \u003cspan class=\"pl-c\"\u003e// Called each time there is a new data snapshot. You may want to use this method\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e// to hide a loading spinner or check for the \"no documents\" state and update your UI.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n    }\n\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonError\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eDatabaseError\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ee\u003c/span\u003e) {\n        \u003cspan class=\"pl-c\"\u003e// Called when there is an error getting data. You may want to update\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e// your UI to display an error message to the user.\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n    }\n};\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUsing the \u003ccode\u003eFirebaseRecyclerPagingAdapter\u003c/code\u003e\u003c/h3\u003e\u003ca id=\"user-content-using-the-firebaserecyclerpagingadapter\" class=\"anchor\" aria-label=\"Permalink: Using the FirebaseRecyclerPagingAdapter\" href=\"#using-the-firebaserecyclerpagingadapter\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eFirebaseRecyclerPagingAdapter\u003c/code\u003e binds a \u003ccode\u003eQuery\u003c/code\u003e to a \u003ccode\u003eRecyclerView\u003c/code\u003e by loading documents in pages.\nThis results in a time and memory efficient binding, however it gives up the real-time events\nafforded by the \u003ccode\u003eFirebaseRecyclerAdapter\u003c/code\u003e.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eFirebaseRecyclerPagingAdapter\u003c/code\u003e is built on top of the \u003ca href=\"https://developer.android.com/topic/libraries/architecture/paging/v3-overview\" rel=\"nofollow\"\u003eAndroid Paging 3 Library\u003c/a\u003e.\nBefore using the adapter in your application, you must add a dependency on that library:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-groovy notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"implementation 'androidx.paging:paging-runtime:3.x.x'\"\u003e\u003cpre\u003eimplementation \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003eandroidx.paging:paging-runtime:3.x.x\u003cspan class=\"pl-pds\"\u003e'\u003c/span\u003e\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFirst, configure the adapter by building \u003ccode\u003eDatabasePagingOptions\u003c/code\u003e. Since the paging adapter\nis not appropriate for a chat application (it would not detect new messages), we will consider\nan adapter that loads a generic \u003ccode\u003eItem\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"// The \u0026quot;base query\u0026quot; is a query with no startAt/endAt/limit clauses that the adapter can use\n// to form smaller queries for each page.\nQuery baseQuery = mDatabase.getReference().child(\u0026quot;items\u0026quot;);\n\n// This configuration comes from the Paging 3 Library\n// https://developer.android.com/reference/kotlin/androidx/paging/PagingConfig\nPagingConfig config = new PagingConfig(/* page size */ 20, /* prefetchDistance */ 10,\n    /* enablePlaceHolders */ false);\n\n// The options for the adapter combine the paging configuration with query information\n// and application-specific options for lifecycle, etc.\nDatabasePagingOptions\u0026lt;Item\u0026gt; options = new DatabasePagingOptions.Builder\u0026lt;Item\u0026gt;()\n        .setLifecycleOwner(this)\n        .setQuery(baseQuery, config, Item.class)\n        .build();\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e// The \"base query\" is a query with no startAt/endAt/limit clauses that the adapter can use\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// to form smaller queries for each page.\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003eQuery\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ebaseQuery\u003c/span\u003e = \u003cspan class=\"pl-s1\"\u003emDatabase\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003egetReference\u003c/span\u003e().\u003cspan class=\"pl-en\"\u003echild\u003c/span\u003e(\u003cspan class=\"pl-s\"\u003e\"items\"\u003c/span\u003e);\n\n\u003cspan class=\"pl-c\"\u003e// This configuration comes from the Paging 3 Library\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// https://developer.android.com/reference/kotlin/androidx/paging/PagingConfig\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003ePagingConfig\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e = \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003ePagingConfig\u003c/span\u003e(\u003cspan class=\"pl-c\"\u003e/* page size */\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e20\u003c/span\u003e, \u003cspan class=\"pl-c\"\u003e/* prefetchDistance */\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e10\u003c/span\u003e,\n    \u003cspan class=\"pl-c\"\u003e/* enablePlaceHolders */\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003efalse\u003c/span\u003e);\n\n\u003cspan class=\"pl-c\"\u003e// The options for the adapter combine the paging configuration with query information\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// and application-specific options for lifecycle, etc.\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003eDatabasePagingOptions\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eItem\u003c/span\u003e\u0026gt; \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e = \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eDatabasePagingOptions\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eBuilder\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eItem\u003c/span\u003e\u0026gt;()\n        .\u003cspan class=\"pl-en\"\u003esetLifecycleOwner\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003ethis\u003c/span\u003e)\n        .\u003cspan class=\"pl-en\"\u003esetQuery\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ebaseQuery\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003econfig\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eItem\u003c/span\u003e.\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e)\n        .\u003cspan class=\"pl-en\"\u003ebuild\u003c/span\u003e();\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you need to customize how your model class is parsed, you can use a custom \u003ccode\u003eSnapshotParser\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"...setQuery(..., new SnapshotParser\u0026lt;Item\u0026gt;() {\n    @NonNull\n    @Override\n    public Item parseSnapshot(@NonNull DocumentSnapshot snapshot) {\n        return ...;\n    }\n});\"\u003e\u003cpre\u003e...\u003cspan class=\"pl-en\"\u003esetQuery\u003c/span\u003e(..., \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eSnapshotParser\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eItem\u003c/span\u003e\u0026gt;() {\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eNonNull\u003c/span\u003e\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eItem\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eparseSnapshot\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eNonNull\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eDocumentSnapshot\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esnapshot\u003c/span\u003e) {\n        \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e ...;\n    }\n});\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eNext, create the \u003ccode\u003eFirebaseRecyclerPagingAdapter\u003c/code\u003e object. You should already have a \u003ccode\u003eViewHolder\u003c/code\u003e subclass\nfor displaying each item. In this case we will use a custom \u003ccode\u003eItemViewHolder\u003c/code\u003e class:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"FirebaseRecyclerPagingAdapter\u0026lt;Item, ItemViewHolder\u0026gt; adapter =\n        new FirebaseRecyclerPagingAdapter\u0026lt;Item, ItemViewHolder\u0026gt;(options) {\n            @NonNull\n            @Override\n            public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {\n                // Create the ItemViewHolder\n                // ...\n            }\n\n            @Override\n            protected void onBindViewHolder(@NonNull ItemViewHolder holder,\n                                            int position,\n                                            @NonNull Item model) {\n                // Bind the item to the view holder\n                // ...\n            }\n        };\"\u003e\u003cpre\u003e\u003cspan class=\"pl-smi\"\u003eFirebaseRecyclerPagingAdapter\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eItem\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eItemViewHolder\u003c/span\u003e\u0026gt; \u003cspan class=\"pl-s1\"\u003eadapter\u003c/span\u003e =\n        \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eFirebaseRecyclerPagingAdapter\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eItem\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eItemViewHolder\u003c/span\u003e\u0026gt;(\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e) {\n            \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eNonNull\u003c/span\u003e\n            \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eItemViewHolder\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonCreateViewHolder\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eNonNull\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eViewGroup\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eparent\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eint\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eviewType\u003c/span\u003e) {\n                \u003cspan class=\"pl-c\"\u003e// Create the ItemViewHolder\u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n            }\n\n            \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003eprotected\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonBindViewHolder\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eNonNull\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eItemViewHolder\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eholder\u003c/span\u003e,\n                                            \u003cspan class=\"pl-smi\"\u003eint\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eposition\u003c/span\u003e,\n                                            \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eNonNull\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eItem\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emodel\u003c/span\u003e) {\n                \u003cspan class=\"pl-c\"\u003e// Bind the item to the view holder\u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n            }\n        };\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eFinally attach the adapter to your \u003ccode\u003eRecyclerView\u003c/code\u003e with the \u003ccode\u003eRecyclerView#setAdapter()\u003c/code\u003e method.\nDon't forget to also set a \u003ccode\u003eLayoutManager\u003c/code\u003e!\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003e\u003ccode\u003eFirebaseRecyclerPagingAdapter\u003c/code\u003e lifecycle\u003c/h4\u003e\u003ca id=\"user-content-firebaserecyclerpagingadapter-lifecycle\" class=\"anchor\" aria-label=\"Permalink: FirebaseRecyclerPagingAdapter lifecycle\" href=\"#firebaserecyclerpagingadapter-lifecycle\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eStart/stop listening\u003c/h5\u003e\u003ca id=\"user-content-startstop-listening-1\" class=\"anchor\" aria-label=\"Permalink: Start/stop listening\" href=\"#startstop-listening-1\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe \u003ccode\u003eFirebaseRecyclerPagingAdapter\u003c/code\u003e listens for scrolling events and loads additional pages from the\ndatabase only when needed.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eTo begin populating data, call the \u003ccode\u003estartListening()\u003c/code\u003e method. You may want to call this\nin your \u003ccode\u003eonStart()\u003c/code\u003e method. Make sure you have finished any authentication necessary to read the\ndata before calling \u003ccode\u003estartListening()\u003c/code\u003e or your query will fail.\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"@Override\nprotected void onStart() {\n    super.onStart();\n    adapter.startListening();\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eprotected\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonStart\u003c/span\u003e() {\n    \u003cspan class=\"pl-en\"\u003esuper\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eonStart\u003c/span\u003e();\n    \u003cspan class=\"pl-s1\"\u003eadapter\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003estartListening\u003c/span\u003e();\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eSimilarly, the \u003ccode\u003estopListening()\u003c/code\u003e call freezes the data in the \u003ccode\u003eRecyclerView\u003c/code\u003e and prevents any future\nloading of data pages.\u003c/p\u003e\n\u003cp dir=\"auto\"\u003eCall this method when the containing Activity or Fragment stops:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"@Override\nprotected void onStop() {\n    super.onStop();\n    adapter.stopListening();\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n\u003cspan class=\"pl-k\"\u003eprotected\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eonStop\u003c/span\u003e() {\n    \u003cspan class=\"pl-en\"\u003esuper\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eonStop\u003c/span\u003e();\n    \u003cspan class=\"pl-s1\"\u003eadapter\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003estopListening\u003c/span\u003e();\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eAutomatic listening\u003c/h5\u003e\u003ca id=\"user-content-automatic-listening-1\" class=\"anchor\" aria-label=\"Permalink: Automatic listening\" href=\"#automatic-listening-1\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf you don't want to manually start/stop listening you can use\n\u003ca href=\"https://developer.android.com/topic/libraries/architecture/index.html\" rel=\"nofollow\"\u003eAndroid Architecture Components\u003c/a\u003e to automatically manage the lifecycle of the\n\u003ccode\u003eFirebaseRecyclerPagingAdapter\u003c/code\u003e. Pass a \u003ccode\u003eLifecycleOwner\u003c/code\u003e to\n\u003ccode\u003eDatabasePagingOptions.Builder#setLifecycleOwner(...)\u003c/code\u003e and FirebaseUI will automatically\nstart and stop listening in \u003ccode\u003eonStart()\u003c/code\u003e and \u003ccode\u003eonStop()\u003c/code\u003e.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003ePaging events\u003c/h4\u003e\u003ca id=\"user-content-paging-events\" class=\"anchor\" aria-label=\"Permalink: Paging events\" href=\"#paging-events\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhen using the \u003ccode\u003eFirebaseRecyclerPagingAdapter\u003c/code\u003e, you may want to perform some action every time data\nchanges or when there is an error. To do this:\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch5 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eIn Java\u003c/h5\u003e\u003ca id=\"user-content-in-java\" class=\"anchor\" aria-label=\"Permalink: In Java\" href=\"#in-java\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUse the \u003ccode\u003eaddLoadStateListener\u003c/code\u003e method from the adapter:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"adapter.addLoadStateListener(new Function1\u0026lt;CombinedLoadStates, Unit\u0026gt;() {\n            @Override\n            public Unit invoke(CombinedLoadStates states) {\n                LoadState refresh = states.getRefresh();\n                LoadState append = states.getAppend();\n\n                if (refresh instanceof LoadState.Error || append instanceof LoadState.Error) {\n                    // The previous load (either initial or additional) failed. Call\n                    // the retry() method in order to retry the load operation.\n                    // ...\n                }\n\n                if (refresh instanceof LoadState.Loading) {\n                    // The initial Load has begun\n                    // ...\n                }\n\n                if (append instanceof LoadState.Loading) {\n                    // The adapter has started to load an additional page\n                    // ...\n                }\n\n                if (append instanceof LoadState.NotLoading) {\n                    LoadState.NotLoading notLoading = (LoadState.NotLoading) append;\n                    if (notLoading.getEndOfPaginationReached()) {\n                        // The adapter has finished loading all of the data set\n                        // ...\n                        return null;\n                    }\n\n                    if (refresh instanceof LoadState.NotLoading) {\n                        // The previous load (either initial or additional) completed\n                        // ...\n                        return null;\n                    }\n                }\n                return null;\n            }\n        });\"\u003e\u003cpre\u003e\u003cspan class=\"pl-s1\"\u003eadapter\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eaddLoadStateListener\u003c/span\u003e(\u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eFunction1\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eCombinedLoadStates\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eUnit\u003c/span\u003e\u0026gt;() {\n            \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n            \u003cspan class=\"pl-k\"\u003epublic\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eUnit\u003c/span\u003e \u003cspan class=\"pl-en\"\u003einvoke\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eCombinedLoadStates\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003estates\u003c/span\u003e) {\n                \u003cspan class=\"pl-smi\"\u003eLoadState\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003erefresh\u003c/span\u003e = \u003cspan class=\"pl-s1\"\u003estates\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003egetRefresh\u003c/span\u003e();\n                \u003cspan class=\"pl-smi\"\u003eLoadState\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eappend\u003c/span\u003e = \u003cspan class=\"pl-s1\"\u003estates\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003egetAppend\u003c/span\u003e();\n\n                \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003erefresh\u003c/span\u003e \u003cspan class=\"pl-k\"\u003einstanceof\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eError\u003c/span\u003e || \u003cspan class=\"pl-s1\"\u003eappend\u003c/span\u003e \u003cspan class=\"pl-k\"\u003einstanceof\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eError\u003c/span\u003e) {\n                    \u003cspan class=\"pl-c\"\u003e// The previous load (either initial or additional) failed. Call\u003c/span\u003e\n                    \u003cspan class=\"pl-c\"\u003e// the retry() method in order to retry the load operation.\u003c/span\u003e\n                    \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n                }\n\n                \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003erefresh\u003c/span\u003e \u003cspan class=\"pl-k\"\u003einstanceof\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eLoading\u003c/span\u003e) {\n                    \u003cspan class=\"pl-c\"\u003e// The initial Load has begun\u003c/span\u003e\n                    \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n                }\n\n                \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003eappend\u003c/span\u003e \u003cspan class=\"pl-k\"\u003einstanceof\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eLoading\u003c/span\u003e) {\n                    \u003cspan class=\"pl-c\"\u003e// The adapter has started to load an additional page\u003c/span\u003e\n                    \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n                }\n\n                \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003eappend\u003c/span\u003e \u003cspan class=\"pl-k\"\u003einstanceof\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eNotLoading\u003c/span\u003e) {\n                    \u003cspan class=\"pl-smi\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eNotLoading\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003enotLoading\u003c/span\u003e = (\u003cspan class=\"pl-smi\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eNotLoading\u003c/span\u003e) \u003cspan class=\"pl-s1\"\u003eappend\u003c/span\u003e;\n                    \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003enotLoading\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003egetEndOfPaginationReached\u003c/span\u003e()) {\n                        \u003cspan class=\"pl-c\"\u003e// The adapter has finished loading all of the data set\u003c/span\u003e\n                        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n                        \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enull\u003c/span\u003e;\n                    }\n\n                    \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-s1\"\u003erefresh\u003c/span\u003e \u003cspan class=\"pl-k\"\u003einstanceof\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eNotLoading\u003c/span\u003e) {\n                        \u003cspan class=\"pl-c\"\u003e// The previous load (either initial or additional) completed\u003c/span\u003e\n                        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n                        \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enull\u003c/span\u003e;\n                    }\n                }\n                \u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003enull\u003c/span\u003e;\n            }\n        });\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch4 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eIn Kotlin\u003c/h4\u003e\u003ca id=\"user-content-in-kotlin\" class=\"anchor\" aria-label=\"Permalink: In Kotlin\" href=\"#in-kotlin\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eUse the \u003ccode\u003eloadStateFlow\u003c/code\u003e exposed by the adapter, in a Coroutine Scope:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-kotlin notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"// Activities can use lifecycleScope directly, but Fragments should instead use\n// viewLifecycleOwner.lifecycleScope.\nlifecycleScope.launch {\n    pagingAdapter.loadStateFlow.collectLatest { loadStates -\u0026gt;\n        when (loadStates.refresh) {\n            is LoadState.Error -\u0026gt; {\n                // The initial load failed. Call the retry() method\n                // in order to retry the load operation.\n                // ...\n            }\n            is LoadState.Loading -\u0026gt; {\n                // The initial Load has begun\n                // ...\n            }\n        }\n\n        when (loadStates.append) {\n            is LoadState.Error -\u0026gt; {\n                // The additional load failed. Call the retry() method\n                // in order to retry the load operation.\n                // ...\n            }\n            is LoadState.Loading -\u0026gt; {\n                // The adapter has started to load an additional page\n                // ...\n            }\n            is LoadState.NotLoading -\u0026gt; {\n                if (loadStates.append.endOfPaginationReached) {\n                    // The adapter has finished loading all of the data set\n                    // ...\n                }\n                if (loadStates.refresh is LoadState.NotLoading) {\n                    // The previous load (either initial or additional) completed\n                    // ...\n                }\n            }\n        }\n  }\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e Activities can use lifecycleScope directly, but Fragments should instead use\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e viewLifecycleOwner.lifecycleScope.\u003c/span\u003e\nlifecycleScope.launch {\n    pagingAdapter.loadStateFlow.collectLatest { loadStates \u003cspan class=\"pl-k\"\u003e-\u0026gt;\u003c/span\u003e\n        \u003cspan class=\"pl-k\"\u003ewhen\u003c/span\u003e (loadStates.refresh) {\n            \u003cspan class=\"pl-k\"\u003eis\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eError\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e-\u0026gt;\u003c/span\u003e {\n                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e The initial load failed. Call the retry() method\u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e in order to retry the load operation.\u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e ...\u003c/span\u003e\n            }\n            \u003cspan class=\"pl-k\"\u003eis\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eLoading\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e-\u0026gt;\u003c/span\u003e {\n                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e The initial Load has begun\u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e ...\u003c/span\u003e\n            }\n        }\n\n        \u003cspan class=\"pl-k\"\u003ewhen\u003c/span\u003e (loadStates.append) {\n            \u003cspan class=\"pl-k\"\u003eis\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eError\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e-\u0026gt;\u003c/span\u003e {\n                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e The additional load failed. Call the retry() method\u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e in order to retry the load operation.\u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e ...\u003c/span\u003e\n            }\n            \u003cspan class=\"pl-k\"\u003eis\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eLoading\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e-\u0026gt;\u003c/span\u003e {\n                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e The adapter has started to load an additional page\u003c/span\u003e\n                \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e ...\u003c/span\u003e\n            }\n            \u003cspan class=\"pl-k\"\u003eis\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eNotLoading\u003c/span\u003e \u003cspan class=\"pl-k\"\u003e-\u0026gt;\u003c/span\u003e {\n                \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (loadStates.append.endOfPaginationReached) {\n                    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e The adapter has finished loading all of the data set\u003c/span\u003e\n                    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e ...\u003c/span\u003e\n                }\n                \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (loadStates.refresh \u003cspan class=\"pl-k\"\u003eis\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eLoadState\u003c/span\u003e.\u003cspan class=\"pl-en\"\u003eNotLoading\u003c/span\u003e) {\n                    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e The previous load (either initial or additional) completed\u003c/span\u003e\n                    \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e//\u003c/span\u003e ...\u003c/span\u003e\n                }\n            }\n        }\n  }\n}\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUsing FirebaseUI to populate a \u003ccode\u003eListView\u003c/code\u003e\u003c/h2\u003e\u003ca id=\"user-content-using-firebaseui-to-populate-a-listview\" class=\"anchor\" aria-label=\"Permalink: Using FirebaseUI to populate a ListView\" href=\"#using-firebaseui-to-populate-a-listview\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eListView is the older, yet simpler way to handle lists of items. Using it is analogous to\nusing a \u003ccode\u003eFirebaseRecyclerAdapter\u003c/code\u003e, but with \u003ccode\u003eFirebaseListAdapter\u003c/code\u003e instead and no \u003ccode\u003eViewHolder\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"FirebaseListOptions\u0026lt;Chat\u0026gt; options = new FirebaseListOptions.Builder\u0026lt;Chat\u0026gt;()\n        .setQuery(query, Chat.class)\n        .build();\n\nFirebaseListAdapter\u0026lt;Chat\u0026gt; adapter = new FirebaseListAdapter\u0026lt;Chat\u0026gt;(options) {\n    @Override\n    protected void populateView(View v, Chat model, int position) {\n        // Bind the Chat to the view\n        // ...\n    }\n};\"\u003e\u003cpre\u003e\u003cspan class=\"pl-smi\"\u003eFirebaseListOptions\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e\u0026gt; \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e = \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eFirebaseListOptions\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eBuilder\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e\u0026gt;()\n        .\u003cspan class=\"pl-en\"\u003esetQuery\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003equery\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e.\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e)\n        .\u003cspan class=\"pl-en\"\u003ebuild\u003c/span\u003e();\n\n\u003cspan class=\"pl-smi\"\u003eFirebaseListAdapter\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e\u0026gt; \u003cspan class=\"pl-s1\"\u003eadapter\u003c/span\u003e = \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eFirebaseListAdapter\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e\u0026gt;(\u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e) {\n    \u003cspan class=\"pl-c1\"\u003e@\u003c/span\u003e\u003cspan class=\"pl-c1\"\u003eOverride\u003c/span\u003e\n    \u003cspan class=\"pl-k\"\u003eprotected\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003evoid\u003c/span\u003e \u003cspan class=\"pl-en\"\u003epopulateView\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003eView\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ev\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003emodel\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eint\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003eposition\u003c/span\u003e) {\n        \u003cspan class=\"pl-c\"\u003e// Bind the Chat to the view\u003c/span\u003e\n        \u003cspan class=\"pl-c\"\u003e// ...\u003c/span\u003e\n    }\n};\u003c/pre\u003e\u003c/div\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch2 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eUsing FirebaseUI with indexed data\u003c/h2\u003e\u003ca id=\"user-content-using-firebaseui-with-indexed-data\" class=\"anchor\" aria-label=\"Permalink: Using FirebaseUI with indexed data\" href=\"#using-firebaseui-with-indexed-data\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eIf your data is \u003ca href=\"https://firebase.google.com/docs/database/android/structure-data#best_practices_for_data_structure\" rel=\"nofollow\"\u003eproperly indexed\u003c/a\u003e, change your adapter initialization\nto use \u003ccode\u003esetIndexedQuery()\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-java notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"// keyQuery - the Firebase location containing the list of keys to be found in dataRef\n// dataRef - the Firebase location to watch for data changes. Each key found at\n//           keyRef's location represents a list item.\nFirebaseRecyclerOptions\u0026lt;Chat\u0026gt; options = new FirebaseRecyclerOptions.Builder\u0026lt;Chat\u0026gt;()\n        .setIndexedQuery(keyQuery, dataRef, Chat.class)\n        .build();\"\u003e\u003cpre\u003e\u003cspan class=\"pl-c\"\u003e// keyQuery - the Firebase location containing the list of keys to be found in dataRef\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e// dataRef - the Firebase location to watch for data changes. Each key found at\u003c/span\u003e\n\u003cspan class=\"pl-c\"\u003e//           keyRef's location represents a list item.\u003c/span\u003e\n\u003cspan class=\"pl-smi\"\u003eFirebaseRecyclerOptions\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e\u0026gt; \u003cspan class=\"pl-s1\"\u003eoptions\u003c/span\u003e = \u003cspan class=\"pl-k\"\u003enew\u003c/span\u003e \u003cspan class=\"pl-smi\"\u003eFirebaseRecyclerOptions\u003c/span\u003e.\u003cspan class=\"pl-smi\"\u003eBuilder\u003c/span\u003e\u0026lt;\u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e\u0026gt;()\n        .\u003cspan class=\"pl-en\"\u003esetIndexedQuery\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ekeyQuery\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003edataRef\u003c/span\u003e, \u003cspan class=\"pl-smi\"\u003eChat\u003c/span\u003e.\u003cspan class=\"pl-k\"\u003eclass\u003c/span\u003e)\n        .\u003cspan class=\"pl-en\"\u003ebuild\u003c/span\u003e();\u003c/pre\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eWhere \u003ccode\u003ekeyQuery\u003c/code\u003e is the location of your keys, and \u003ccode\u003edataRef\u003c/code\u003e is the location of your data.\u003c/p\u003e\n\u003cdiv class=\"markdown-heading\" dir=\"auto\"\u003e\u003ch3 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\"\u003eA note on ordering\u003c/h3\u003e\u003ca id=\"user-content-a-note-on-ordering\" class=\"anchor\" aria-label=\"Permalink: A note on ordering\" href=\"#a-note-on-ordering\"\u003e\u003csvg data-component=\"Octicon\" class=\"octicon octicon-link\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" height=\"16\" aria-hidden=\"true\"\u003e\u003cpath d=\"m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z\"\u003e\u003c/path\u003e\u003c/svg\u003e\u003c/a\u003e\u003c/div\u003e\n\u003cp dir=\"auto\"\u003eThe order in which you receive your data depends on the order from \u003ccode\u003ekeyRef\u003c/code\u003e, not \u003ccode\u003edataRef\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight highlight-source-js notranslate position-relative overflow-auto\" dir=\"auto\" data-snippet-clipboard-copy-content=\"{\n  \u0026quot;data\u0026quot;: {\n    // This order doesn't matter, the order is taken from keys/(user1 or user2).\n    \u0026quot;3\u0026quot;: true,\n    \u0026quot;1\u0026quot;: \u0026quot;some data\u0026quot;,\n    \u0026quot;2\u0026quot;: 5\n  },\n  \u0026quot;keys\u0026quot;: {\n    // These two users have different orders for their data thanks to key side ordering.\n    \u0026quot;user1\u0026quot;: {\n      \u0026quot;1\u0026quot;: true,\n      \u0026quot;2\u0026quot;: true,\n      \u0026quot;3\u0026quot;: true\n    },\n    \u0026quot;user2\u0026quot;: {\n      \u0026quot;3\u0026quot;: true,\n      \u0026quot;2\u0026quot;: true,\n      \u0026quot;1\u0026quot;: true\n    }\n  }\n}\"\u003e\u003cpre\u003e\u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n  \u003cspan class=\"pl-s\"\u003e\"data\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e// This order doesn't matter, the order is taken from keys/(user1 or user2).\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"3\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"1\"\u003c/span\u003e: \u003cspan class=\"pl-s\"\u003e\"some data\"\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"2\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003e5\u003c/span\u003e\n  \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n  \u003cspan class=\"pl-s\"\u003e\"keys\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n    \u003cspan class=\"pl-c\"\u003e// These two users have different orders for their data thanks to key side ordering.\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"user1\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e\"1\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e\"2\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e\"3\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n    \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n    \u003cspan class=\"pl-s\"\u003e\"user2\"\u003c/span\u003e: \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e\"3\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e\"2\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\u003cspan class=\"pl-kos\"\u003e,\u003c/span\u003e\n      \u003cspan class=\"pl-s\"\u003e\"1\"\u003c/span\u003e: \u003cspan class=\"pl-c1\"\u003etrue\u003c/span\u003e\n    \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n  \u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\n\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003c/article\u003e","richTextTruncated":false,"renderedFileInfo":null,"symbols":{"timed_out":false,"not_analyzed":false,"symbols":[{"name":"FirebaseUI for Realtime Database","fully_qualified_name":"FirebaseUI for Realtime Database","kind":"section_1","ident_start":2,"ident_end":34,"extent_start":0,"extent_end":17705,"ident_utf16":{"start":{"line_number":0,"utf16_col":2},"end":{"line_number":0,"utf16_col":34}},"extent_utf16":{"start":{"line_number":0,"utf16_col":0},"end":{"line_number":522,"utf16_col":0}}},{"name":"Table of contents","fully_qualified_name":"Table of contents","kind":"section_2","ident_start":356,"ident_end":373,"extent_start":353,"extent_end":846,"ident_utf16":{"start":{"line_number":9,"utf16_col":3},"end":{"line_number":9,"utf16_col":20}},"extent_utf16":{"start":{"line_number":9,"utf16_col":0},"end":{"line_number":20,"utf16_col":0}}},{"name":"Data model","fully_qualified_name":"Data model","kind":"section_2","ident_start":849,"ident_end":859,"extent_start":846,"extent_end":3225,"ident_utf16":{"start":{"line_number":20,"utf16_col":3},"end":{"line_number":20,"utf16_col":13}},"extent_utf16":{"start":{"line_number":20,"utf16_col":0},"end":{"line_number":108,"utf16_col":0}}},{"name":"Querying","fully_qualified_name":"Querying","kind":"section_3","ident_start":2153,"ident_end":2161,"extent_start":2149,"extent_end":3225,"ident_utf16":{"start":{"line_number":63,"utf16_col":4},"end":{"line_number":63,"utf16_col":12}},"extent_utf16":{"start":{"line_number":63,"utf16_col":0},"end":{"line_number":108,"utf16_col":0}}},{"name":"Using FirebaseUI to populate a `RecyclerView`","fully_qualified_name":"Using FirebaseUI to populate a `RecyclerView`","kind":"section_2","ident_start":3228,"ident_end":3273,"extent_start":3225,"extent_end":15456,"ident_utf16":{"start":{"line_number":108,"utf16_col":3},"end":{"line_number":108,"utf16_col":48}},"extent_utf16":{"start":{"line_number":108,"utf16_col":0},"end":{"line_number":454,"utf16_col":0}}},{"name":"Choosing an adapter","fully_qualified_name":"Choosing an adapter","kind":"section_3","ident_start":3555,"ident_end":3574,"extent_start":3551,"extent_end":4178,"ident_utf16":{"start":{"line_number":116,"utf16_col":4},"end":{"line_number":116,"utf16_col":23}},"extent_utf16":{"start":{"line_number":116,"utf16_col":0},"end":{"line_number":127,"utf16_col":0}}},{"name":"Using the FirebaseRecyclerAdapter","fully_qualified_name":"Using the FirebaseRecyclerAdapter","kind":"section_3","ident_start":4182,"ident_end":4215,"extent_start":4178,"extent_end":7980,"ident_utf16":{"start":{"line_number":127,"utf16_col":4},"end":{"line_number":127,"utf16_col":37}},"extent_utf16":{"start":{"line_number":127,"utf16_col":0},"end":{"line_number":243,"utf16_col":0}}},{"name":"FirebaseRecyclerAdapter lifecycle","fully_qualified_name":"FirebaseRecyclerAdapter lifecycle","kind":"section_4","ident_start":5987,"ident_end":6020,"extent_start":5982,"extent_end":7150,"ident_utf16":{"start":{"line_number":181,"utf16_col":5},"end":{"line_number":181,"utf16_col":38}},"extent_utf16":{"start":{"line_number":181,"utf16_col":0},"end":{"line_number":217,"utf16_col":0}}},{"name":"Start/stop listening","fully_qualified_name":"Start/stop listening","kind":"section_5","ident_start":6028,"ident_end":6048,"extent_start":6022,"extent_end":6762,"ident_utf16":{"start":{"line_number":183,"utf16_col":6},"end":{"line_number":183,"utf16_col":26}},"extent_utf16":{"start":{"line_number":183,"utf16_col":0},"end":{"line_number":209,"utf16_col":0}}},{"name":"Automatic listening","fully_qualified_name":"Automatic listening","kind":"section_5","ident_start":6768,"ident_end":6787,"extent_start":6762,"extent_end":7150,"ident_utf16":{"start":{"line_number":209,"utf16_col":6},"end":{"line_number":209,"utf16_col":25}},"extent_utf16":{"start":{"line_number":209,"utf16_col":0},"end":{"line_number":217,"utf16_col":0}}},{"name":"Data and error events","fully_qualified_name":"Data and error events","kind":"section_4","ident_start":7155,"ident_end":7176,"extent_start":7150,"extent_end":7980,"ident_utf16":{"start":{"line_number":217,"utf16_col":5},"end":{"line_number":217,"utf16_col":26}},"extent_utf16":{"start":{"line_number":217,"utf16_col":0},"end":{"line_number":243,"utf16_col":0}}},{"name":"Using the `FirebaseRecyclerPagingAdapter`","fully_qualified_name":"Using the `FirebaseRecyclerPagingAdapter`","kind":"section_3","ident_start":7984,"ident_end":8025,"extent_start":7980,"extent_end":15456,"ident_utf16":{"start":{"line_number":243,"utf16_col":4},"end":{"line_number":243,"utf16_col":45}},"extent_utf16":{"start":{"line_number":243,"utf16_col":0},"end":{"line_number":454,"utf16_col":0}}},{"name":"`FirebaseRecyclerPagingAdapter` lifecycle","fully_qualified_name":"`FirebaseRecyclerPagingAdapter` lifecycle","kind":"section_4","ident_start":10855,"ident_end":10896,"extent_start":10850,"extent_end":12091,"ident_utf16":{"start":{"line_number":316,"utf16_col":5},"end":{"line_number":316,"utf16_col":46}},"extent_utf16":{"start":{"line_number":316,"utf16_col":0},"end":{"line_number":356,"utf16_col":0}}},{"name":"Start/stop listening","fully_qualified_name":"Start/stop listening","kind":"section_5","ident_start":10904,"ident_end":10924,"extent_start":10898,"extent_end":11699,"ident_utf16":{"start":{"line_number":318,"utf16_col":6},"end":{"line_number":318,"utf16_col":26}},"extent_utf16":{"start":{"line_number":318,"utf16_col":0},"end":{"line_number":348,"utf16_col":0}}},{"name":"Automatic listening","fully_qualified_name":"Automatic listening","kind":"section_5","ident_start":11705,"ident_end":11724,"extent_start":11699,"extent_end":12091,"ident_utf16":{"start":{"line_number":348,"utf16_col":6},"end":{"line_number":348,"utf16_col":25}},"extent_utf16":{"start":{"line_number":348,"utf16_col":0},"end":{"line_number":356,"utf16_col":0}}},{"name":"Paging events","fully_qualified_name":"Paging events","kind":"section_4","ident_start":12096,"ident_end":12109,"extent_start":12091,"extent_end":13953,"ident_utf16":{"start":{"line_number":356,"utf16_col":5},"end":{"line_number":356,"utf16_col":18}},"extent_utf16":{"start":{"line_number":356,"utf16_col":0},"end":{"line_number":407,"utf16_col":0}}},{"name":"In Java","fully_qualified_name":"In Java","kind":"section_5","ident_start":12265,"ident_end":12272,"extent_start":12259,"extent_end":13953,"ident_utf16":{"start":{"line_number":361,"utf16_col":6},"end":{"line_number":361,"utf16_col":13}},"extent_utf16":{"start":{"line_number":361,"utf16_col":0},"end":{"line_number":407,"utf16_col":0}}},{"name":"In Kotlin","fully_qualified_name":"In Kotlin","kind":"section_4","ident_start":13958,"ident_end":13967,"extent_start":13953,"extent_end":15456,"ident_utf16":{"start":{"line_number":407,"utf16_col":5},"end":{"line_number":407,"utf16_col":14}},"extent_utf16":{"start":{"line_number":407,"utf16_col":0},"end":{"line_number":454,"utf16_col":0}}},{"name":"Using FirebaseUI to populate a `ListView`","fully_qualified_name":"Using FirebaseUI to populate a `ListView`","kind":"section_2","ident_start":15459,"ident_end":15500,"extent_start":15456,"extent_end":16053,"ident_utf16":{"start":{"line_number":454,"utf16_col":3},"end":{"line_number":454,"utf16_col":44}},"extent_utf16":{"start":{"line_number":454,"utf16_col":0},"end":{"line_number":473,"utf16_col":0}}},{"name":"Using FirebaseUI with indexed data","fully_qualified_name":"Using FirebaseUI with indexed data","kind":"section_2","ident_start":16056,"ident_end":16090,"extent_start":16053,"extent_end":17705,"ident_utf16":{"start":{"line_number":473,"utf16_col":3},"end":{"line_number":473,"utf16_col":37}},"extent_utf16":{"start":{"line_number":473,"utf16_col":0},"end":{"line_number":522,"utf16_col":0}}},{"name":"A note on ordering","fully_qualified_name":"A note on ordering","kind":"section_3","ident_start":16695,"ident_end":16713,"extent_start":16691,"extent_end":17705,"ident_utf16":{"start":{"line_number":489,"utf16_col":4},"end":{"line_number":489,"utf16_col":22}},"extent_utf16":{"start":{"line_number":489,"utf16_col":0},"end":{"line_number":522,"utf16_col":0}}}]}},"codeViewLayoutRoute":{"repo":{"id":38835213,"defaultBranch":"master","name":"FirebaseUI-Android","ownerLogin":"firebase","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2015-07-09T17:31:09.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/1335026?v=4","public":true,"private":false,"isOrgOwned":true,"isArchived":false},"currentUser":null,"uploadToken":"FFqPpFPzPS4ArlD344jWpGt3puhAWd7kE2fyNu9cGcm7grGzOya4AmRnR79g65WJrmmqVKS-kI1OcIeyLKUCDg","allShortcutsEnabled":false,"treeExpanded":true,"path":"database/README.md","symbolsExpanded":false,"refInfo":{"name":"master","listCacheKey":"v0:1789441713.0","canEdit":false,"currentOid":"0f47c5c58be1e4225dafcad06c7d4e86949ba892"},"helpUrl":"https://docs.github.com","githubDevUrl":null},"codeViewFileTreeLayoutRoute":{"fileTree":{"database":{"items":[{"name":"src","path":"database/src","contentType":"directory"},{"name":"README.md","path":"database/README.md","contentType":"file"},{"name":"build.gradle.kts","path":"database/build.gradle.kts","contentType":"file"},{"name":"gradle.properties","path":"database/gradle.properties","contentType":"file"},{"name":"proguard-rules.pro","path":"database/proguard-rules.pro","contentType":"file"}],"totalCount":5},"":{"items":[{"name":".agents","path":".agents","contentType":"directory"},{"name":".github","path":".github","contentType":"directory"},{"name":".idea","path":".idea","contentType":"directory"},{"name":".opensource","path":".opensource","contentType":"directory"},{"name":"app","path":"app","contentType":"directory"},{"name":"auth","path":"auth","contentType":"directory"},{"name":"buildSrc","path":"buildSrc","contentType":"directory"},{"name":"common","path":"common","contentType":"directory"},{"name":"database","path":"database","contentType":"directory"},{"name":"doc-images","path":"doc-images","contentType":"directory"},{"name":"docs","path":"docs","contentType":"directory"},{"name":"e2eTest","path":"e2eTest","contentType":"directory"},{"name":"firestore","path":"firestore","contentType":"directory"},{"name":"gradle","path":"gradle","contentType":"directory"},{"name":"internal","path":"internal","contentType":"directory"},{"name":"library","path":"library","contentType":"directory"},{"name":"lint","path":"lint","contentType":"directory"},{"name":"okf-bundle","path":"okf-bundle","contentType":"directory"},{"name":"proguard-tests","path":"proguard-tests","contentType":"directory"},{"name":"scripts","path":"scripts","contentType":"directory"},{"name":"storage","path":"storage","contentType":"directory"},{"name":".gitignore","path":".gitignore","contentType":"file"},{"name":"AGENTS.md","path":"AGENTS.md","contentType":"file"},{"name":"CHANGELOG.md","path":"CHANGELOG.md","contentType":"file"},{"name":"CLAUDE.md","path":"CLAUDE.md","contentType":"file"},{"name":"CONTRIBUTING.md","path":"CONTRIBUTING.md","contentType":"file"},{"name":"GETTING_STARTED.md","path":"GETTING_STARTED.md","contentType":"file"},{"name":"LICENSE","path":"LICENSE","contentType":"file"},{"name":"README.md","path":"README.md","contentType":"file"},{"name":"build.gradle.kts","path":"build.gradle.kts","contentType":"file"},{"name":"gradle.properties","path":"gradle.properties","contentType":"file"},{"name":"gradlew","path":"gradlew","contentType":"file"},{"name":"gradlew.bat","path":"gradlew.bat","contentType":"file"},{"name":"settings.gradle","path":"settings.gradle","contentType":"file"}],"totalCount":34}},"fileTreeProcessingTime":24.957925999999997,"foldersToFetch":[]},"codeViewBlobLayoutRoute":{"codeLineWrapEnabled":false,"refInfo":{"name":"master","listCacheKey":"v0:1789441713.0","canEdit":false,"refType":"branch","currentOid":"0f47c5c58be1e4225dafcad06c7d4e86949ba892","canEditOnDefaultBranch":false,"fileExistsOnDefault":true},"path":"database/README.md","blob":{"copilotSWEAgentEnabled":false,"dependabotInfo":{"showConfigurationBanner":false,"configFilePath":null,"networkDependabotPath":"/firebase/FirebaseUI-Android/network/updates","dismissConfigurationNoticePath":"/settings/dismiss-notice/dependabot_configuration_notice","configurationNoticeDismissed":null},"displayName":"README.md","displayUrl":"https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md?raw=true","headerInfo":{"blobSize":"17.3 KB","deleteTooltip":"You must be signed in to make or propose changes","editTooltip":"You must be signed in to make or propose changes","ghDesktopPath":"https://desktop.github.com","isGitLfs":false,"onBranch":true,"shortPath":"f1d27f2","siteNavLoginPath":"/login?return_to=https%3A%2F%2Fgithub.com%2Ffirebase%2FFirebaseUI-Android%2Fblob%2Fmaster%2Fdatabase%2FREADME.md","isCSV":false,"isRichtext":true,"lineInfo":{"truncatedLoc":"522","truncatedSloc":"412"},"mode":"file"},"image":false,"isCodeownersFile":null,"isPlain":false,"isValidLegacyIssueTemplate":false,"isIssueTemplate":false,"isDiscussionTemplate":false,"language":"Markdown","languageID":222,"large":false,"planSupportInfo":{"repoIsFork":null,"repoOwnedByCurrentUser":null,"requestFullPath":"/firebase/FirebaseUI-Android/blob/master/database/README.md","showFreeOrgGatedFeatureMessage":null,"showPlanSupportBanner":null,"upgradeDataAttributes":null,"upgradePath":null},"publishBannersInfo":{"dismissActionNoticePath":"/settings/dismiss-notice/publish_action_from_dockerfile","releasePath":"/firebase/FirebaseUI-Android/releases/new?marketplace=true","showPublishActionBanner":false},"rawBlobUrl":"https://github.com/firebase/FirebaseUI-Android/raw/refs/heads/master/database/README.md","renderImageOrRaw":false,"shortPath":null,"symbolsEnabled":true,"tabSize":4,"topBannersInfo":{"overridingGlobalFundingFile":false,"globalPreferredFundingPath":null,"showInvalidCitationWarning":false,"citationHelpUrl":"https://docs.github.com/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-citation-files","actionsOnboardingTip":null},"truncated":false,"viewable":true,"workflowRedirectUrl":null},"copilotInfo":null,"copilotAccessAllowed":false,"copilotSpacesEnabled":false,"modelsAccessAllowed":false,"modelsRepoIntegrationEnabled":false,"isMarketplaceEnabled":true},"codeViewBlobLayoutRoute.StyledBlob":{"rawLines":["# FirebaseUI for Realtime Database","","FirebaseUI makes it simple to bind data from the Firebase Realtime Database to your app's UI.","","Before using this library, you should be familiar with the following topics:","","* [Working with lists of data in Firebase Realtime Database][firebase-lists].","* [Displaying lists of data using a RecyclerView][recyclerview].","","## Table of contents","","1. [Data model](#data-model)","1. [Querying](#querying)","1. [Populating a RecyclerView](#using-firebaseui-to-populate-a-recyclerview)","   1. [Using the FirebaseRecyclerAdapter](#using-the-firebaserecycleradapter)","   1. [Using the FirebaseRecyclerPagingAdapter](#using-the-firebaserecyclerpagingadapter)","1. [Populating a ListView](#using-firebaseui-to-populate-a-listview)","1. [Handling indexed data](#using-firebaseui-with-indexed-data)","   1. [Warnings](#a-note-on-ordering)","","## Data model","","Imagine you have a chat app where each chat message is an item in the `chats` node","of your database. In your app, you may represent a chat message like this:","","```java","public class Chat {","    private String mName;","    private String mMessage;","    private String mUid;","","    public Chat() {}  // Needed for Firebase","","    public Chat(String name, String message, String uid) {","        mName = name;","        mMessage = message;","        mUid = uid;","    }","","    public String getName() { return mName; }","","    public void setName(String name) { mName = name; }","","    public String getMessage() { return mMessage; }","","    public void setMessage(String message) { mMessage = message; }","","    public String getUid() { return mUid; }","","    public void setUid(String uid) { mUid = uid; }","}","```","","A few things to note about this model class:","","* The getters and setters follow the JavaBean naming pattern which allows Firebase to map","  the data to field names (ex: `getName()` provides the `name` field).","* The class has an empty constructor, which is required for Firebase's automatic data mapping.","","For a properly constructed model class like the `Chat` class above, Firebase can perform automatic","serialization in `DatabaseReference#setValue()` and automatic deserialization in","`DataSnapshot#getValue()`.","","### Querying","","On the main screen of your app, you may want to show the 50 most recent chat messages. With Firebase","you would use the following query:","","```java","Query query = FirebaseDatabase.getInstance()","        .getReference()","        .child(\"chats\")","        .limitToLast(50);","```","","To retrieve this data without FirebaseUI, you might use `addChildEventListener` to listen for","live updates:","","```java","ChildEventListener childEventListener = new ChildEventListener() {","    @Override","    public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {","        // ...","    }","","    @Override","    public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {","        // ...","    }","","    @Override","    public void onChildRemoved(DataSnapshot dataSnapshot) {","        // ...","    }","","    @Override","    public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {","        // ...","    }","","    @Override","    public void onCancelled(DatabaseError databaseError) {","        // ...","    }","};","query.addChildEventListener(childEventListener);","```","","## Using FirebaseUI to populate a `RecyclerView`","","If you're displaying a list of data, you likely want to bind the `Chat` objects to a `RecyclerView`.","This means implementing a custom `RecyclerView.Adapter` and coordinating updates with the","`ChildEventListener`.","","Fear not, FirebaseUI does all of this for you automatically!","","### Choosing an adapter","","FirebaseUI offers two types of RecyclerView adapters for the Realtime Database:","","  * `FirebaseRecyclerAdapter` — binds a `Query` to a `RecyclerView` and responds to all real-time","    events included items being added, removed, moved, or changed. Best used with small result sets","    since all results are loaded at once.","  * `FirebaseRecyclerPagingAdapter` — binds a `Query` to a `RecyclerView` by loading data in pages. Best","    used with large, static data sets. Real-time events are not respected by this adapter, so it","    will not detect new/removed items or changes to items already loaded.","","### Using the FirebaseRecyclerAdapter","","The `FirebaseRecyclerAdapter` binds a `Query` to a `RecyclerView`. When data is added, removed,","or changed these updates are automatically applied to your UI in real time.","","First, configure the adapter by building `FirebaseRecyclerOptions`. In this case we will continue","with our chat example:","","```java"," FirebaseRecyclerOptions\u003cChat\u003e options =","                new FirebaseRecyclerOptions.Builder\u003cChat\u003e()","                        .setQuery(query, Chat.class)","                        .build();","```","","If you need to customize how your model class is parsed, you can use a custom `SnapshotParser`:","","```java","...setQuery(..., new SnapshotParser\u003cChat\u003e() {","    @NonNull","    @Override","    public Chat parseSnapshot(@NonNull DataSnapshot snapshot) {","        return ...;","    }","});","```","","Next create the `FirebaseRecyclerAdapter` object. You should already have a `ViewHolder` subclass","for displaying each item. In this case we will use a custom `ChatHolder` class:","","```java","FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter\u003cChat, ChatHolder\u003e(options) {","    @Override","    public ChatHolder onCreateViewHolder(ViewGroup parent, int viewType) {","        // Create a new instance of the ViewHolder, in this case we are using a custom","        // layout called R.layout.message for each item","        View view = LayoutInflater.from(parent.getContext())","                .inflate(R.layout.message, parent, false);","","        return new ChatHolder(view);","    }","","    @Override","    protected void onBindViewHolder(ChatHolder holder, int position, Chat model) {","        // Bind the Chat object to the ChatHolder","        // ...","    }","};","```","","Finally attach the adapter to your `RecyclerView` with the `RecyclerView#setAdapter()` method.","Don't forget to also set a `LayoutManager`!","","","#### FirebaseRecyclerAdapter lifecycle","","##### Start/stop listening","","The `FirebaseRecyclerAdapter` uses an event listener to monitor changes to the Firebase query.","To begin listening for data, call the `startListening()` method. You may want to call this in your","`onStart()` method. Make sure you have finished any authentication necessary to read the data","before calling `startListening()` or your query will fail.","","```java","@Override","protected void onStart() {","    super.onStart();","    adapter.startListening();","}","```","","Similarly, the `stopListening()` call removes the event  listener and all data in the adapter.","Call this method when the containing Activity or Fragment stops:","","```java","@Override","protected void onStop() {","    super.onStop();","    adapter.stopListening();","}","```","","##### Automatic listening","","If you don't want to manually start/stop listening you can use","[Android Architecture Components][arch-components] to automatically manage the lifecycle of the","`FirebaseRecyclerAdapter`. Pass a `LifecycleOwner` to","`FirebaseRecyclerOptions.Builder#setLifecycleOwner(...)` and FirebaseUI will automatically","start and stop listening in `onStart()` and `onStop()`.","","#### Data and error events","","When using the `FirebaseRecyclerAdapter` you may want to perform some action every time data","changes or when there is an error. To do this, override the `onDataChanged()` and `onError()`","methods of the adapter:","","```java","FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter\u003cChat, ChatHolder\u003e(options) {","    // ...","","    @Override","    public void onDataChanged() {","        // Called each time there is a new data snapshot. You may want to use this method","        // to hide a loading spinner or check for the \"no documents\" state and update your UI.","        // ...","    }","","    @Override","    public void onError(DatabaseError e) {","        // Called when there is an error getting data. You may want to update","        // your UI to display an error message to the user.","        // ...","    }","};","```","","### Using the `FirebaseRecyclerPagingAdapter`","","The `FirebaseRecyclerPagingAdapter` binds a `Query` to a `RecyclerView` by loading documents in pages.","This results in a time and memory efficient binding, however it gives up the real-time events","afforded by the `FirebaseRecyclerAdapter`.","","The `FirebaseRecyclerPagingAdapter` is built on top of the [Android Paging 3 Library][paging-support].","Before using the adapter in your application, you must add a dependency on that library:","","```groovy","implementation 'androidx.paging:paging-runtime:3.x.x'","```","","First, configure the adapter by building `DatabasePagingOptions`. Since the paging adapter","is not appropriate for a chat application (it would not detect new messages), we will consider","an adapter that loads a generic `Item`:","","```java","// The \"base query\" is a query with no startAt/endAt/limit clauses that the adapter can use","// to form smaller queries for each page.","Query baseQuery = mDatabase.getReference().child(\"items\");","","// This configuration comes from the Paging 3 Library","// https://developer.android.com/reference/kotlin/androidx/paging/PagingConfig","PagingConfig config = new PagingConfig(/* page size */ 20, /* prefetchDistance */ 10,","    /* enablePlaceHolders */ false);","","// The options for the adapter combine the paging configuration with query information","// and application-specific options for lifecycle, etc.","DatabasePagingOptions\u003cItem\u003e options = new DatabasePagingOptions.Builder\u003cItem\u003e()","        .setLifecycleOwner(this)","        .setQuery(baseQuery, config, Item.class)","        .build();","```","","If you need to customize how your model class is parsed, you can use a custom `SnapshotParser`:","","```java","...setQuery(..., new SnapshotParser\u003cItem\u003e() {","    @NonNull","    @Override","    public Item parseSnapshot(@NonNull DocumentSnapshot snapshot) {","        return ...;","    }","});","```","","Next, create the `FirebaseRecyclerPagingAdapter` object. You should already have a `ViewHolder` subclass","for displaying each item. In this case we will use a custom `ItemViewHolder` class:","","```java","FirebaseRecyclerPagingAdapter\u003cItem, ItemViewHolder\u003e adapter =","        new FirebaseRecyclerPagingAdapter\u003cItem, ItemViewHolder\u003e(options) {","            @NonNull","            @Override","            public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {","                // Create the ItemViewHolder","                // ...","            }","","            @Override","            protected void onBindViewHolder(@NonNull ItemViewHolder holder,","                                            int position,","                                            @NonNull Item model) {","                // Bind the item to the view holder","                // ...","            }","        };","```","","Finally attach the adapter to your `RecyclerView` with the `RecyclerView#setAdapter()` method.","Don't forget to also set a `LayoutManager`!","","#### `FirebaseRecyclerPagingAdapter` lifecycle","","##### Start/stop listening","","The `FirebaseRecyclerPagingAdapter` listens for scrolling events and loads additional pages from the","database only when needed.","","To begin populating data, call the `startListening()` method. You may want to call this","in your `onStart()` method. Make sure you have finished any authentication necessary to read the","data before calling `startListening()` or your query will fail.","","```java","@Override","protected void onStart() {","    super.onStart();","    adapter.startListening();","}","```","","Similarly, the `stopListening()` call freezes the data in the `RecyclerView` and prevents any future","loading of data pages.","","Call this method when the containing Activity or Fragment stops:","","```java","@Override","protected void onStop() {","    super.onStop();","    adapter.stopListening();","}","```","","##### Automatic listening","","If you don't want to manually start/stop listening you can use","[Android Architecture Components][arch-components] to automatically manage the lifecycle of the","`FirebaseRecyclerPagingAdapter`. Pass a `LifecycleOwner` to","`DatabasePagingOptions.Builder#setLifecycleOwner(...)` and FirebaseUI will automatically","start and stop listening in `onStart()` and `onStop()`.","","#### Paging events","","When using the `FirebaseRecyclerPagingAdapter`, you may want to perform some action every time data","changes or when there is an error. To do this:","","##### In Java","","Use the `addLoadStateListener` method from the adapter:","","```java","adapter.addLoadStateListener(new Function1\u003cCombinedLoadStates, Unit\u003e() {","            @Override","            public Unit invoke(CombinedLoadStates states) {","                LoadState refresh = states.getRefresh();","                LoadState append = states.getAppend();","","                if (refresh instanceof LoadState.Error || append instanceof LoadState.Error) {","                    // The previous load (either initial or additional) failed. Call","                    // the retry() method in order to retry the load operation.","                    // ...","                }","","                if (refresh instanceof LoadState.Loading) {","                    // The initial Load has begun","                    // ...","                }","","                if (append instanceof LoadState.Loading) {","                    // The adapter has started to load an additional page","                    // ...","                }","","                if (append instanceof LoadState.NotLoading) {","                    LoadState.NotLoading notLoading = (LoadState.NotLoading) append;","                    if (notLoading.getEndOfPaginationReached()) {","                        // The adapter has finished loading all of the data set","                        // ...","                        return null;","                    }","","                    if (refresh instanceof LoadState.NotLoading) {","                        // The previous load (either initial or additional) completed","                        // ...","                        return null;","                    }","                }","                return null;","            }","        });","```","","#### In Kotlin","","Use the `loadStateFlow` exposed by the adapter, in a Coroutine Scope:","","```kotlin","// Activities can use lifecycleScope directly, but Fragments should instead use","// viewLifecycleOwner.lifecycleScope.","lifecycleScope.launch {","    pagingAdapter.loadStateFlow.collectLatest { loadStates -\u003e","        when (loadStates.refresh) {","            is LoadState.Error -\u003e {","                // The initial load failed. Call the retry() method","                // in order to retry the load operation.","                // ...","            }","            is LoadState.Loading -\u003e {","                // The initial Load has begun","                // ...","            }","        }","","        when (loadStates.append) {","            is LoadState.Error -\u003e {","                // The additional load failed. Call the retry() method","                // in order to retry the load operation.","                // ...","            }","            is LoadState.Loading -\u003e {","                // The adapter has started to load an additional page","                // ...","            }","            is LoadState.NotLoading -\u003e {","                if (loadStates.append.endOfPaginationReached) {","                    // The adapter has finished loading all of the data set","                    // ...","                }","                if (loadStates.refresh is LoadState.NotLoading) {","                    // The previous load (either initial or additional) completed","                    // ...","                }","            }","        }","  }","}","```","","","## Using FirebaseUI to populate a `ListView`","","ListView is the older, yet simpler way to handle lists of items. Using it is analogous to","using a `FirebaseRecyclerAdapter`, but with `FirebaseListAdapter` instead and no `ViewHolder`:","","```java","FirebaseListOptions\u003cChat\u003e options = new FirebaseListOptions.Builder\u003cChat\u003e()","        .setQuery(query, Chat.class)","        .build();","","FirebaseListAdapter\u003cChat\u003e adapter = new FirebaseListAdapter\u003cChat\u003e(options) {","    @Override","    protected void populateView(View v, Chat model, int position) {","        // Bind the Chat to the view","        // ...","    }","};","```","","## Using FirebaseUI with indexed data","","If your data is [properly indexed][indexed-data], change your adapter initialization","to use `setIndexedQuery()`:","","```java","// keyQuery - the Firebase location containing the list of keys to be found in dataRef","// dataRef - the Firebase location to watch for data changes. Each key found at","//           keyRef's location represents a list item.","FirebaseRecyclerOptions\u003cChat\u003e options = new FirebaseRecyclerOptions.Builder\u003cChat\u003e()","        .setIndexedQuery(keyQuery, dataRef, Chat.class)","        .build();","```","","Where `keyQuery` is the location of your keys, and `dataRef` is the location of your data.","","### A note on ordering","","The order in which you receive your data depends on the order from `keyRef`, not `dataRef`:","","```javascript","{","  \"data\": {","    // This order doesn't matter, the order is taken from keys/(user1 or user2).","    \"3\": true,","    \"1\": \"some data\",","    \"2\": 5","  },","  \"keys\": {","    // These two users have different orders for their data thanks to key side ordering.","    \"user1\": {","      \"1\": true,","      \"2\": true,","      \"3\": true","    },","    \"user2\": {","      \"3\": true,","      \"2\": true,","      \"1\": true","    }","  }","}","```","","[firebase-lists]: https://firebase.google.com/docs/database/android/lists-of-data","[indexed-data]: https://firebase.google.com/docs/database/android/structure-data#best_practices_for_data_structure","[recyclerview]: https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView","[arch-components]: https://developer.android.com/topic/libraries/architecture/index.html","[paging-support]: https://developer.android.com/topic/libraries/architecture/paging/v3-overview"],"stylingDirectives":[[[0,34,"pl-mh"],[2,34,"pl-en"]],[],[],[],[],[],[[0,1,"pl-v"],[2,3,"pl-s"],[59,60,"pl-s"],[60,61,"pl-s"],[61,75,"pl-en"],[75,76,"pl-s"]],[[0,1,"pl-v"],[2,3,"pl-s"],[48,49,"pl-s"],[49,50,"pl-s"],[50,62,"pl-en"],[62,63,"pl-s"]],[],[[0,20,"pl-mh"],[3,20,"pl-en"]],[],[[0,1,"pl-s"],[1,2,"pl-v"],[3,4,"pl-s"],[14,15,"pl-s"],[15,16,"pl-s"],[16,27,"pl-corl"],[27,28,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,4,"pl-s"],[12,13,"pl-s"],[13,14,"pl-s"],[14,23,"pl-corl"],[23,24,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,4,"pl-s"],[29,30,"pl-s"],[30,31,"pl-s"],[31,75,"pl-corl"],[75,76,"pl-s"]],[[3,4,"pl-s"],[4,5,"pl-v"],[6,7,"pl-s"],[40,41,"pl-s"],[41,42,"pl-s"],[42,76,"pl-corl"],[76,77,"pl-s"]],[[3,4,"pl-s"],[4,5,"pl-v"],[6,7,"pl-s"],[46,47,"pl-s"],[47,48,"pl-s"],[48,88,"pl-corl"],[88,89,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,4,"pl-s"],[25,26,"pl-s"],[26,27,"pl-s"],[27,67,"pl-corl"],[67,68,"pl-s"]],[[0,1,"pl-s"],[1,2,"pl-v"],[3,4,"pl-s"],[25,26,"pl-s"],[26,27,"pl-s"],[27,62,"pl-corl"],[62,63,"pl-s"]],[[3,4,"pl-s"],[4,5,"pl-v"],[6,7,"pl-s"],[15,16,"pl-s"],[16,17,"pl-s"],[17,36,"pl-corl"],[36,37,"pl-s"]],[],[[0,13,"pl-mh"],[3,13,"pl-en"]],[],[[70,71,"pl-s"],[71,76,"pl-c1"],[76,77,"pl-s"]],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,6,"pl-k"],[7,12,"pl-k"],[13,17,"pl-en"]],[[4,11,"pl-k"],[12,18,"pl-smi"]],[[4,11,"pl-k"],[12,18,"pl-smi"]],[[4,11,"pl-k"],[12,18,"pl-smi"]],[],[[4,10,"pl-k"],[11,15,"pl-en"],[22,44,"pl-c"],[22,24,"pl-c"]],[],[[4,10,"pl-k"],[11,15,"pl-en"],[16,22,"pl-smi"],[23,27,"pl-v"],[29,35,"pl-smi"],[36,43,"pl-v"],[45,51,"pl-smi"],[52,55,"pl-v"]],[[14,15,"pl-k"]],[[17,18,"pl-k"]],[[13,14,"pl-k"]],[],[],[[4,10,"pl-k"],[11,17,"pl-smi"],[18,25,"pl-en"],[30,36,"pl-k"]],[],[[4,10,"pl-k"],[11,15,"pl-k"],[16,23,"pl-en"],[24,30,"pl-smi"],[31,35,"pl-v"],[45,46,"pl-k"]],[],[[4,10,"pl-k"],[11,17,"pl-smi"],[18,28,"pl-en"],[33,39,"pl-k"]],[],[[4,10,"pl-k"],[11,15,"pl-k"],[16,26,"pl-en"],[27,33,"pl-smi"],[34,41,"pl-v"],[54,55,"pl-k"]],[],[[4,10,"pl-k"],[11,17,"pl-smi"],[18,24,"pl-en"],[29,35,"pl-k"]],[],[[4,10,"pl-k"],[11,15,"pl-k"],[16,22,"pl-en"],[23,29,"pl-smi"],[30,33,"pl-v"],[42,43,"pl-k"]],[],[[0,3,"pl-s"]],[],[],[],[[0,1,"pl-v"]],[[31,32,"pl-s"],[32,41,"pl-c1"],[41,42,"pl-s"],[56,57,"pl-s"],[57,61,"pl-c1"],[61,62,"pl-s"]],[[0,1,"pl-v"]],[],[[48,49,"pl-s"],[49,53,"pl-c1"],[53,54,"pl-s"]],[[17,18,"pl-s"],[18,46,"pl-c1"],[46,47,"pl-s"]],[[0,1,"pl-s"],[1,24,"pl-c1"],[24,25,"pl-s"]],[],[[0,12,"pl-mh"],[4,12,"pl-en"]],[],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,5,"pl-smi"],[12,13,"pl-k"],[14,30,"pl-smi"],[30,31,"pl-k"]],[],[[15,22,"pl-s"],[15,16,"pl-pds"],[21,22,"pl-pds"]],[[21,23,"pl-c1"]],[[0,3,"pl-s"]],[],[[56,57,"pl-s"],[57,78,"pl-c1"],[78,79,"pl-s"]],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,18,"pl-smi"],[38,39,"pl-k"],[40,43,"pl-k"],[44,62,"pl-smi"]],[[4,13,"pl-k"]],[[4,10,"pl-k"],[11,15,"pl-k"],[16,28,"pl-en"],[29,41,"pl-smi"],[42,54,"pl-v"],[56,62,"pl-smi"],[63,80,"pl-v"]],[[8,14,"pl-c"],[8,10,"pl-c"]],[],[],[[4,13,"pl-k"]],[[4,10,"pl-k"],[11,15,"pl-k"],[16,30,"pl-en"],[31,43,"pl-smi"],[44,56,"pl-v"],[58,64,"pl-smi"],[65,82,"pl-v"]],[[8,14,"pl-c"],[8,10,"pl-c"]],[],[],[[4,13,"pl-k"]],[[4,10,"pl-k"],[11,15,"pl-k"],[16,30,"pl-en"],[31,43,"pl-smi"],[44,56,"pl-v"]],[[8,14,"pl-c"],[8,10,"pl-c"]],[],[],[[4,13,"pl-k"]],[[4,10,"pl-k"],[11,15,"pl-k"],[16,28,"pl-en"],[29,41,"pl-smi"],[42,54,"pl-v"],[56,62,"pl-smi"],[63,80,"pl-v"]],[[8,14,"pl-c"],[8,10,"pl-c"]],[],[],[[4,13,"pl-k"]],[[4,10,"pl-k"],[11,15,"pl-k"],[16,27,"pl-en"],[28,41,"pl-smi"],[42,55,"pl-v"]],[[8,14,"pl-c"],[8,10,"pl-c"]],[],[],[[5,6,"pl-k"]],[[0,3,"pl-s"]],[],[[0,48,"pl-mh"],[3,48,"pl-en"],[34,35,"pl-s"],[35,47,"pl-c1"],[47,48,"pl-s"]],[],[[65,66,"pl-s"],[66,70,"pl-c1"],[70,71,"pl-s"],[85,86,"pl-s"],[86,98,"pl-c1"],[98,99,"pl-s"]],[[33,34,"pl-s"],[34,54,"pl-c1"],[54,55,"pl-s"]],[[0,1,"pl-s"],[1,19,"pl-c1"],[19,20,"pl-s"]],[],[],[],[[0,23,"pl-mh"],[4,23,"pl-en"]],[],[],[],[[2,3,"pl-v"],[4,5,"pl-s"],[5,28,"pl-c1"],[28,29,"pl-s"],[40,41,"pl-s"],[41,46,"pl-c1"],[46,47,"pl-s"],[53,54,"pl-s"],[54,66,"pl-c1"],[66,67,"pl-s"]],[],[],[[2,3,"pl-v"],[4,5,"pl-s"],[5,34,"pl-c1"],[34,35,"pl-s"],[46,47,"pl-s"],[47,52,"pl-c1"],[52,53,"pl-s"],[59,60,"pl-s"],[60,72,"pl-c1"],[72,73,"pl-s"]],[],[],[],[[0,37,"pl-mh"],[4,37,"pl-en"]],[],[[4,5,"pl-s"],[5,28,"pl-c1"],[28,29,"pl-s"],[38,39,"pl-s"],[39,44,"pl-c1"],[44,45,"pl-s"],[51,52,"pl-s"],[52,64,"pl-c1"],[64,65,"pl-s"]],[],[],[[41,42,"pl-s"],[42,65,"pl-c1"],[65,66,"pl-s"]],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[1,30,"pl-k"],[25,29,"pl-smi"],[39,40,"pl-k"]],[[16,19,"pl-k"],[20,43,"pl-smi"],[44,57,"pl-k"],[52,56,"pl-smi"]],[[41,45,"pl-smi"],[45,46,"pl-k"]],[],[[0,3,"pl-s"]],[],[[78,79,"pl-s"],[79,93,"pl-c1"],[93,94,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,2,"pl-c1"],[2,3,"pl-k"],[12,15,"pl-c1"],[17,20,"pl-k"],[21,41,"pl-k"],[36,40,"pl-smi"]],[[4,12,"pl-k"]],[[4,13,"pl-k"]],[[4,10,"pl-k"],[11,15,"pl-smi"],[16,29,"pl-en"],[30,38,"pl-k"],[39,51,"pl-smi"],[52,60,"pl-v"]],[[8,14,"pl-k"],[15,18,"pl-c1"]],[],[],[[0,3,"pl-s"]],[],[[16,17,"pl-s"],[17,40,"pl-c1"],[40,41,"pl-s"],[76,77,"pl-s"],[77,87,"pl-c1"],[87,88,"pl-s"]],[[60,61,"pl-s"],[61,71,"pl-c1"],[71,72,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,23,"pl-smi"],[32,33,"pl-k"],[34,37,"pl-k"],[38,79,"pl-k"],[62,66,"pl-smi"],[68,78,"pl-smi"]],[[4,13,"pl-k"]],[[4,10,"pl-k"],[11,21,"pl-smi"],[22,40,"pl-en"],[41,50,"pl-smi"],[51,57,"pl-v"],[59,62,"pl-k"],[63,71,"pl-v"]],[[8,86,"pl-c"],[8,10,"pl-c"]],[[8,55,"pl-c"],[8,10,"pl-c"]],[[8,12,"pl-smi"],[18,19,"pl-k"],[20,34,"pl-smi"],[34,35,"pl-k"],[46,47,"pl-k"]],[[25,26,"pl-smi"],[26,27,"pl-k"],[33,34,"pl-k"],[51,56,"pl-c1"]],[],[[8,14,"pl-k"],[15,18,"pl-k"],[19,29,"pl-smi"]],[],[],[[4,13,"pl-k"]],[[4,13,"pl-k"],[14,18,"pl-k"],[19,35,"pl-en"],[36,46,"pl-smi"],[47,53,"pl-v"],[55,58,"pl-k"],[59,67,"pl-v"],[69,73,"pl-smi"],[74,79,"pl-v"]],[[8,49,"pl-c"],[8,10,"pl-c"]],[[8,14,"pl-c"],[8,10,"pl-c"]],[],[],[[0,3,"pl-s"]],[],[[35,36,"pl-s"],[36,48,"pl-c1"],[48,49,"pl-s"],[59,60,"pl-s"],[60,85,"pl-c1"],[85,86,"pl-s"]],[[27,28,"pl-s"],[28,41,"pl-c1"],[41,42,"pl-s"]],[],[],[[0,38,"pl-mh"],[5,38,"pl-en"]],[],[[0,26,"pl-mh"],[6,26,"pl-en"]],[],[[4,5,"pl-s"],[5,28,"pl-c1"],[28,29,"pl-s"]],[[38,39,"pl-s"],[39,55,"pl-c1"],[55,56,"pl-s"]],[[0,1,"pl-s"],[1,10,"pl-c1"],[10,11,"pl-s"]],[[15,16,"pl-s"],[16,32,"pl-c1"],[32,33,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,9,"pl-k"]],[[0,9,"pl-k"],[10,14,"pl-k"]],[[4,9,"pl-c1"],[9,10,"pl-k"]],[[11,12,"pl-k"]],[],[[0,3,"pl-s"]],[],[[15,16,"pl-s"],[16,31,"pl-c1"],[31,32,"pl-s"]],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,9,"pl-k"]],[[0,9,"pl-k"],[10,14,"pl-k"]],[[4,9,"pl-c1"],[9,10,"pl-k"]],[[11,12,"pl-k"]],[],[[0,3,"pl-s"]],[],[[0,25,"pl-mh"],[6,25,"pl-en"]],[],[],[[0,1,"pl-s"],[32,33,"pl-s"],[33,34,"pl-s"],[34,49,"pl-en"],[49,50,"pl-s"]],[[0,1,"pl-s"],[1,24,"pl-c1"],[24,25,"pl-s"],[34,35,"pl-s"],[35,49,"pl-c1"],[49,50,"pl-s"]],[[0,1,"pl-s"],[1,55,"pl-c1"],[55,56,"pl-s"]],[[28,29,"pl-s"],[29,38,"pl-c1"],[38,39,"pl-s"],[44,45,"pl-s"],[45,53,"pl-c1"],[53,54,"pl-s"]],[],[[0,26,"pl-mh"],[5,26,"pl-en"]],[],[[15,16,"pl-s"],[16,39,"pl-c1"],[39,40,"pl-s"]],[[60,61,"pl-s"],[61,76,"pl-c1"],[76,77,"pl-s"],[82,83,"pl-s"],[83,92,"pl-c1"],[92,93,"pl-s"]],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,23,"pl-smi"],[32,33,"pl-k"],[34,37,"pl-k"],[38,79,"pl-k"],[62,66,"pl-smi"],[68,78,"pl-smi"]],[[4,10,"pl-c"],[4,6,"pl-c"]],[],[[4,13,"pl-k"]],[[4,10,"pl-k"],[11,15,"pl-k"],[16,29,"pl-en"]],[[8,89,"pl-c"],[8,10,"pl-c"]],[[8,94,"pl-c"],[8,10,"pl-c"]],[[8,14,"pl-c"],[8,10,"pl-c"]],[],[],[[4,13,"pl-k"]],[[4,10,"pl-k"],[11,15,"pl-k"],[16,23,"pl-en"],[24,37,"pl-smi"],[38,39,"pl-v"]],[[8,77,"pl-c"],[8,10,"pl-c"]],[[8,59,"pl-c"],[8,10,"pl-c"]],[[8,14,"pl-c"],[8,10,"pl-c"]],[],[],[[0,3,"pl-s"]],[],[[0,45,"pl-mh"],[4,45,"pl-en"],[14,15,"pl-s"],[15,44,"pl-c1"],[44,45,"pl-s"]],[],[[4,5,"pl-s"],[5,34,"pl-c1"],[34,35,"pl-s"],[44,45,"pl-s"],[45,50,"pl-c1"],[50,51,"pl-s"],[57,58,"pl-s"],[58,70,"pl-c1"],[70,71,"pl-s"]],[],[[16,17,"pl-s"],[17,40,"pl-c1"],[40,41,"pl-s"]],[],[[4,5,"pl-s"],[5,34,"pl-c1"],[34,35,"pl-s"],[59,60,"pl-s"],[84,85,"pl-s"],[85,86,"pl-s"],[86,100,"pl-en"],[100,101,"pl-s"]],[],[],[[0,3,"pl-s"],[3,9,"pl-en"],[9,9,"pl-c1"]],[[0,53,"pl-c1"]],[[0,0,"pl-c1"],[0,3,"pl-s"]],[],[[41,42,"pl-s"],[42,63,"pl-c1"],[63,64,"pl-s"]],[],[[32,33,"pl-s"],[33,37,"pl-c1"],[37,38,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,91,"pl-c"],[0,2,"pl-c"]],[[0,41,"pl-c"],[0,2,"pl-c"]],[[0,5,"pl-smi"],[16,17,"pl-k"],[27,28,"pl-k"],[42,43,"pl-k"],[49,56,"pl-s"],[49,50,"pl-pds"],[55,56,"pl-pds"]],[],[[0,53,"pl-c"],[0,2,"pl-c"]],[[0,78,"pl-c"],[0,2,"pl-c"]],[[0,12,"pl-smi"],[20,21,"pl-k"],[22,25,"pl-k"],[26,38,"pl-smi"],[39,54,"pl-c"],[39,41,"pl-c"],[52,54,"pl-c"],[55,57,"pl-c1"],[59,81,"pl-c"],[59,61,"pl-c"],[79,81,"pl-c"],[82,84,"pl-c1"]],[[4,28,"pl-c"],[4,6,"pl-c"],[26,28,"pl-c"],[29,34,"pl-c1"]],[],[[0,86,"pl-c"],[0,2,"pl-c"]],[[0,55,"pl-c"],[0,2,"pl-c"]],[[0,27,"pl-k"],[22,26,"pl-smi"],[36,37,"pl-k"],[38,41,"pl-k"],[42,63,"pl-smi"],[64,77,"pl-k"],[72,76,"pl-smi"]],[[27,31,"pl-c1"]],[[37,41,"pl-smi"],[41,42,"pl-k"]],[],[[0,3,"pl-s"]],[],[[78,79,"pl-s"],[79,93,"pl-c1"],[93,94,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,2,"pl-c1"],[2,3,"pl-k"],[12,15,"pl-c1"],[17,20,"pl-k"],[21,41,"pl-k"],[36,40,"pl-smi"]],[[4,12,"pl-k"]],[[4,13,"pl-k"]],[[4,10,"pl-k"],[11,15,"pl-smi"],[16,29,"pl-en"],[30,38,"pl-k"],[39,55,"pl-smi"],[56,64,"pl-v"]],[[8,14,"pl-k"],[15,18,"pl-c1"]],[],[],[[0,3,"pl-s"]],[],[[17,18,"pl-s"],[18,47,"pl-c1"],[47,48,"pl-s"],[83,84,"pl-s"],[84,94,"pl-c1"],[94,95,"pl-s"]],[[60,61,"pl-s"],[61,75,"pl-c1"],[75,76,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,51,"pl-k"],[30,34,"pl-smi"],[36,50,"pl-smi"],[60,61,"pl-k"]],[[8,11,"pl-k"],[12,63,"pl-k"],[42,46,"pl-smi"],[48,62,"pl-smi"]],[[12,20,"pl-k"]],[[12,21,"pl-k"]],[[12,18,"pl-k"],[19,33,"pl-smi"],[34,52,"pl-en"],[53,61,"pl-k"],[62,71,"pl-smi"],[72,78,"pl-v"],[80,83,"pl-k"],[84,92,"pl-v"]],[[16,44,"pl-c"],[16,18,"pl-c"]],[[16,22,"pl-c"],[16,18,"pl-c"]],[],[],[[12,21,"pl-k"]],[[12,21,"pl-k"],[22,26,"pl-k"],[27,43,"pl-en"],[44,52,"pl-k"],[53,67,"pl-smi"],[68,74,"pl-v"]],[[44,47,"pl-k"],[48,56,"pl-v"]],[[44,52,"pl-k"],[53,57,"pl-smi"],[58,63,"pl-v"]],[[16,51,"pl-c"],[16,18,"pl-c"]],[[16,22,"pl-c"],[16,18,"pl-c"]],[],[],[[0,3,"pl-s"]],[],[[35,36,"pl-s"],[36,48,"pl-c1"],[48,49,"pl-s"],[59,60,"pl-s"],[60,85,"pl-c1"],[85,86,"pl-s"]],[[27,28,"pl-s"],[28,41,"pl-c1"],[41,42,"pl-s"]],[],[[0,46,"pl-mh"],[5,46,"pl-en"],[5,6,"pl-s"],[6,35,"pl-c1"],[35,36,"pl-s"]],[],[[0,26,"pl-mh"],[6,26,"pl-en"]],[],[[4,5,"pl-s"],[5,34,"pl-c1"],[34,35,"pl-s"]],[],[],[[35,36,"pl-s"],[36,52,"pl-c1"],[52,53,"pl-s"]],[[8,9,"pl-s"],[9,18,"pl-c1"],[18,19,"pl-s"]],[[20,21,"pl-s"],[21,37,"pl-c1"],[37,38,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,9,"pl-k"]],[[0,9,"pl-k"],[10,14,"pl-k"]],[[4,9,"pl-c1"],[9,10,"pl-k"]],[[11,12,"pl-k"]],[],[[0,3,"pl-s"]],[],[[15,16,"pl-s"],[16,31,"pl-c1"],[31,32,"pl-s"],[62,63,"pl-s"],[63,75,"pl-c1"],[75,76,"pl-s"]],[],[],[],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,9,"pl-k"]],[[0,9,"pl-k"],[10,14,"pl-k"]],[[4,9,"pl-c1"],[9,10,"pl-k"]],[[11,12,"pl-k"]],[],[[0,3,"pl-s"]],[],[[0,25,"pl-mh"],[6,25,"pl-en"]],[],[],[[0,1,"pl-s"],[32,33,"pl-s"],[33,34,"pl-s"],[34,49,"pl-en"],[49,50,"pl-s"]],[[0,1,"pl-s"],[1,30,"pl-c1"],[30,31,"pl-s"],[40,41,"pl-s"],[41,55,"pl-c1"],[55,56,"pl-s"]],[[0,1,"pl-s"],[1,53,"pl-c1"],[53,54,"pl-s"]],[[28,29,"pl-s"],[29,38,"pl-c1"],[38,39,"pl-s"],[44,45,"pl-s"],[45,53,"pl-c1"],[53,54,"pl-s"]],[],[[0,18,"pl-mh"],[5,18,"pl-en"]],[],[[15,16,"pl-s"],[16,45,"pl-c1"],[45,46,"pl-s"]],[],[],[[0,13,"pl-mh"],[6,13,"pl-en"]],[],[[8,9,"pl-s"],[9,29,"pl-c1"],[29,30,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[7,8,"pl-k"],[29,32,"pl-k"],[33,68,"pl-k"],[43,61,"pl-smi"],[63,67,"pl-smi"]],[[12,21,"pl-k"]],[[12,18,"pl-k"],[19,23,"pl-smi"],[24,30,"pl-en"],[31,49,"pl-smi"],[50,56,"pl-v"]],[[16,25,"pl-smi"],[34,35,"pl-k"],[42,43,"pl-k"]],[[16,25,"pl-smi"],[33,34,"pl-k"],[41,42,"pl-k"]],[],[[16,18,"pl-k"],[28,38,"pl-k"],[39,48,"pl-smi"],[48,49,"pl-k"],[49,54,"pl-smi"],[55,57,"pl-k"],[65,75,"pl-k"],[76,85,"pl-smi"],[85,86,"pl-k"],[86,91,"pl-smi"]],[[20,84,"pl-c"],[20,22,"pl-c"]],[[20,79,"pl-c"],[20,22,"pl-c"]],[[20,26,"pl-c"],[20,22,"pl-c"]],[],[],[[16,18,"pl-k"],[28,38,"pl-k"],[39,48,"pl-smi"],[48,49,"pl-k"],[49,56,"pl-smi"]],[[20,49,"pl-c"],[20,22,"pl-c"]],[[20,26,"pl-c"],[20,22,"pl-c"]],[],[],[[16,18,"pl-k"],[27,37,"pl-k"],[38,47,"pl-smi"],[47,48,"pl-k"],[48,55,"pl-smi"]],[[20,73,"pl-c"],[20,22,"pl-c"]],[[20,26,"pl-c"],[20,22,"pl-c"]],[],[],[[16,18,"pl-k"],[27,37,"pl-k"],[38,47,"pl-smi"],[47,48,"pl-k"],[48,58,"pl-smi"]],[[20,29,"pl-smi"],[29,30,"pl-k"],[30,40,"pl-smi"],[52,53,"pl-k"],[55,64,"pl-smi"],[64,65,"pl-k"],[65,75,"pl-smi"]],[[20,22,"pl-k"],[34,35,"pl-k"]],[[24,79,"pl-c"],[24,26,"pl-c"]],[[24,30,"pl-c"],[24,26,"pl-c"]],[[24,30,"pl-k"],[31,35,"pl-c1"]],[],[],[[20,22,"pl-k"],[32,42,"pl-k"],[43,52,"pl-smi"],[52,53,"pl-k"],[53,63,"pl-smi"]],[[24,85,"pl-c"],[24,26,"pl-c"]],[[24,30,"pl-c"],[24,26,"pl-c"]],[[24,30,"pl-k"],[31,35,"pl-c1"]],[],[],[[16,22,"pl-k"],[23,27,"pl-c1"]],[],[],[[0,3,"pl-s"]],[],[[0,14,"pl-mh"],[5,14,"pl-en"]],[],[[8,9,"pl-s"],[9,22,"pl-c1"],[22,23,"pl-s"]],[],[[0,3,"pl-s"],[3,9,"pl-en"]],[[0,79,"pl-c"],[0,2,"pl-c"]],[[0,37,"pl-c"],[0,2,"pl-c"]],[],[[59,61,"pl-k"]],[[8,12,"pl-k"]],[[12,14,"pl-k"],[15,24,"pl-en"],[25,30,"pl-en"],[31,33,"pl-k"]],[[16,67,"pl-c"],[16,18,"pl-c"]],[[16,56,"pl-c"],[16,18,"pl-c"]],[[16,22,"pl-c"],[16,18,"pl-c"]],[],[[12,14,"pl-k"],[15,24,"pl-en"],[25,32,"pl-en"],[33,35,"pl-k"]],[[16,45,"pl-c"],[16,18,"pl-c"]],[[16,22,"pl-c"],[16,18,"pl-c"]],[],[],[],[[8,12,"pl-k"]],[[12,14,"pl-k"],[15,24,"pl-en"],[25,30,"pl-en"],[31,33,"pl-k"]],[[16,70,"pl-c"],[16,18,"pl-c"]],[[16,56,"pl-c"],[16,18,"pl-c"]],[[16,22,"pl-c"],[16,18,"pl-c"]],[],[[12,14,"pl-k"],[15,24,"pl-en"],[25,32,"pl-en"],[33,35,"pl-k"]],[[16,69,"pl-c"],[16,18,"pl-c"]],[[16,22,"pl-c"],[16,18,"pl-c"]],[],[[12,14,"pl-k"],[15,24,"pl-en"],[25,35,"pl-en"],[36,38,"pl-k"]],[[16,18,"pl-k"]],[[20,75,"pl-c"],[20,22,"pl-c"]],[[20,26,"pl-c"],[20,22,"pl-c"]],[],[[16,18,"pl-k"],[39,41,"pl-k"],[42,51,"pl-en"],[52,62,"pl-en"]],[[20,81,"pl-c"],[20,22,"pl-c"]],[[20,26,"pl-c"],[20,22,"pl-c"]],[],[],[],[],[],[[0,3,"pl-s"]],[],[],[[0,44,"pl-mh"],[3,44,"pl-en"],[34,35,"pl-s"],[35,43,"pl-c1"],[43,44,"pl-s"]],[],[],[[8,9,"pl-s"],[9,32,"pl-c1"],[32,33,"pl-s"],[44,45,"pl-s"],[45,64,"pl-c1"],[64,65,"pl-s"],[81,82,"pl-s"],[82,92,"pl-c1"],[92,93,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,25,"pl-k"],[20,24,"pl-smi"],[34,35,"pl-k"],[36,39,"pl-k"],[40,59,"pl-smi"],[60,73,"pl-k"],[68,72,"pl-smi"]],[[25,29,"pl-smi"],[29,30,"pl-k"]],[],[],[[0,25,"pl-k"],[20,24,"pl-smi"],[34,35,"pl-k"],[36,39,"pl-k"],[40,65,"pl-k"],[60,64,"pl-smi"]],[[4,13,"pl-k"]],[[4,13,"pl-k"],[14,18,"pl-k"],[19,31,"pl-en"],[32,36,"pl-smi"],[37,38,"pl-v"],[40,44,"pl-smi"],[45,50,"pl-v"],[52,55,"pl-k"],[56,64,"pl-v"]],[[8,36,"pl-c"],[8,10,"pl-c"]],[[8,14,"pl-c"],[8,10,"pl-c"]],[],[],[[0,3,"pl-s"]],[],[[0,37,"pl-mh"],[3,37,"pl-en"]],[],[[16,17,"pl-s"],[33,34,"pl-s"],[34,35,"pl-s"],[35,47,"pl-en"],[47,48,"pl-s"]],[[7,8,"pl-s"],[8,25,"pl-c1"],[25,26,"pl-s"]],[],[[0,3,"pl-s"],[3,7,"pl-en"]],[[0,86,"pl-c"],[0,2,"pl-c"]],[[0,79,"pl-c"],[0,2,"pl-c"]],[[0,54,"pl-c"],[0,2,"pl-c"]],[[0,29,"pl-k"],[24,28,"pl-smi"],[38,39,"pl-k"],[40,43,"pl-k"],[44,67,"pl-smi"],[68,81,"pl-k"],[76,80,"pl-smi"]],[[44,48,"pl-smi"],[48,49,"pl-k"]],[],[[0,3,"pl-s"]],[],[[6,7,"pl-s"],[7,15,"pl-c1"],[15,16,"pl-s"],[51,52,"pl-s"],[52,59,"pl-c1"],[59,60,"pl-s"]],[],[[0,22,"pl-mh"],[4,22,"pl-en"]],[],[[67,68,"pl-s"],[68,74,"pl-c1"],[74,75,"pl-s"],[81,82,"pl-s"],[82,89,"pl-c1"],[89,90,"pl-s"]],[],[[0,3,"pl-s"],[3,13,"pl-en"]],[],[[2,8,"pl-s"],[2,3,"pl-pds"],[7,8,"pl-pds"],[8,9,"pl-k"]],[[4,80,"pl-c"],[4,6,"pl-c"]],[[4,7,"pl-s"],[4,5,"pl-pds"],[6,7,"pl-pds"],[7,8,"pl-k"],[9,13,"pl-c1"]],[[4,7,"pl-s"],[4,5,"pl-pds"],[6,7,"pl-pds"],[7,8,"pl-k"],[9,20,"pl-s"],[9,10,"pl-pds"],[19,20,"pl-pds"]],[[4,7,"pl-s"],[4,5,"pl-pds"],[6,7,"pl-pds"],[7,8,"pl-k"],[9,10,"pl-c1"]],[],[[2,8,"pl-s"],[2,3,"pl-pds"],[7,8,"pl-pds"],[8,9,"pl-k"]],[[4,88,"pl-c"],[4,6,"pl-c"]],[[4,11,"pl-s"],[4,5,"pl-pds"],[10,11,"pl-pds"],[11,12,"pl-k"]],[[6,9,"pl-s"],[6,7,"pl-pds"],[8,9,"pl-pds"],[9,10,"pl-k"],[11,15,"pl-c1"]],[[6,9,"pl-s"],[6,7,"pl-pds"],[8,9,"pl-pds"],[9,10,"pl-k"],[11,15,"pl-c1"]],[[6,9,"pl-s"],[6,7,"pl-pds"],[8,9,"pl-pds"],[9,10,"pl-k"],[11,15,"pl-c1"]],[],[[4,11,"pl-s"],[4,5,"pl-pds"],[10,11,"pl-pds"],[11,12,"pl-k"]],[[6,9,"pl-s"],[6,7,"pl-pds"],[8,9,"pl-pds"],[9,10,"pl-k"],[11,15,"pl-c1"]],[[6,9,"pl-s"],[6,7,"pl-pds"],[8,9,"pl-pds"],[9,10,"pl-k"],[11,15,"pl-c1"]],[[6,9,"pl-s"],[6,7,"pl-pds"],[8,9,"pl-pds"],[9,10,"pl-k"],[11,15,"pl-c1"]],[],[],[],[[0,3,"pl-s"]],[],[[0,1,"pl-s"],[1,15,"pl-en"],[15,16,"pl-s"],[18,81,"pl-corl"]],[[0,1,"pl-s"],[1,13,"pl-en"],[13,14,"pl-s"],[16,114,"pl-corl"]],[[0,1,"pl-s"],[1,13,"pl-en"],[13,14,"pl-s"],[16,97,"pl-corl"]],[[0,1,"pl-s"],[1,16,"pl-en"],[16,17,"pl-s"],[19,88,"pl-corl"]],[[0,1,"pl-s"],[1,15,"pl-en"],[15,16,"pl-s"],[18,95,"pl-corl"]]],"colorizedLines":null}},"title":"FirebaseUI-Android/database/README.md at master · firebase/FirebaseUI-Android","appPayload":{},"meta":{"title":"FirebaseUI-Android/database/README.md at master · firebase/FirebaseUI-Android"}}</script>
  <div data-target="react-app.reactRoot"><meta name="github-code-view-meta-stats" id="github-code-view-meta-stats" data-hydrostats="publish"/> <!-- --> <a hidden="" id="code-view-repo-link" href="/firebase/FirebaseUI-Android" data-discover="true"></a> <div class="d-none"></div><div><div style="--spacing:var(--spacing-none)" class="prc-PageLayout-PageLayoutRoot--KH-d" data-component="SplitPageLayout" data-has-sidebar="true"><div class="prc-PageLayout-SidebarWrapper-kLG4B CopilotSidePanelSidebar-module__SidePanel__L3O0C CopilotSidePanelSidebar-module__HiddenSidePanel__TBRGn" style="--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="end" data-sticky="true" data-responsive-variant="fullscreen"><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-SidebarVerticalDivider-0Rl0V" data-component="PageLayout.VerticalDivider" data-variant="line" data-position="end" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="450" aria-valuemax="768" aria-valuenow="544" aria-valuetext="Pane width 544 pixels" tabindex="0"></div></div><div class="prc-PageLayout-Sidebar-iciWg" data-component="SplitPageLayout.Sidebar" data-resizable="true" style="--spacing:var(--spacing-normal);--pane-min-width:450px;--pane-max-width:768px;--pane-width-custom:544px;--pane-width-size:var(--pane-width-custom);--pane-width:544px"><div class="height-full" data-testid="copilot-code-view-side-panel"><div id="copilot-side-panel-content" class="height-full"></div></div></div></div><div class="prc-PageLayout-PageLayoutWrapper-2BhU2" data-width="full"><div class="prc-PageLayout-PageLayoutContent-BneH9"><div id="repos-file-tree-sidebar" class="CodeViewFileTreeLayout-module__sidebar__n_Aau" tabindex="0"><div class="prc-PageLayout-PaneWrapper-pHPop ReposFileTreePane-module__Pane__rBZpI ReposFileTreePane-module__HideTree__AYZnm ReposFileTreePane-module__HidePane__VHAVt" style="--offset-header:0px;--spacing-row:var(--spacing-none);--spacing-column:var(--spacing-none)" data-is-hidden="false" data-position="start" data-sticky="true"><div class="prc-PageLayout-HorizontalDivider-JLVqp prc-PageLayout-PaneHorizontalDivider-9tbnE" data-component="PageLayout.HorizontalDivider" data-variant-regular="none" data-variant-narrow="none" data-position="start" style="--spacing-divider:var(--spacing-none);--spacing:var(--spacing-none)"></div><div class="prc-PageLayout-Pane-AyzHK" data-component="SplitPageLayout.Pane" data-resizable="true" style="--spacing:var(--spacing-none);--pane-min-width:256px;--pane-max-width:calc(100vw - var(--pane-max-width-diff));--pane-width-size:var(--pane-width-large);--pane-width:320px"></div><div class="prc-PageLayout-VerticalDivider-9QRmK prc-PageLayout-PaneVerticalDivider-le57g" data-component="PageLayout.VerticalDivider" data-variant-narrow="none" data-variant-regular="line" data-variant-wide="line" data-position="start" style="--spacing:var(--spacing-none)"><div class="prc-PageLayout-DraggableHandle-9s6B4" data-component="PageLayout.DragHandle" role="slider" aria-label="Draggable pane splitter" aria-valuemin="256" aria-valuemax="600" aria-valuenow="320" aria-valuetext="Pane width 320 pixels" tabindex="0"></div></div></div></div><div data-component="SplitPageLayout.Content" class="prc-PageLayout-ContentWrapper-gR9eG"><div class="prc-PageLayout-Content-xWL-A" data-width="full" style="--spacing:var(--spacing-none)"><div class="SharedPageLayout-module__content__IwGAp" data-selector="repos-split-pane-content" id="repos-split-pane-content" tabindex="0"> <!-- --> <div class="container CodeViewHeader-module__Box__JkPOb"><div class="CodeViewHeader-module__StickyHeader__Qn7UN" id="StickyHeader"><div class="CodeViewHeader-module__Box_1__SbNDV"><div class="CodeViewHeader-module__Box_2__TB46f"><div class="react-code-view-header-wrap--narrow CodeViewHeader-module__Box_3__q1zUL"><div class="CodeViewHeader-module__treeToggleWrapper__RQ__9"><h2 class="use-tree-pane-module__Heading__s4QbZ prc-Heading-Heading-MtWFE" data-component="Heading"><button data-component="Button" type="button" aria-label="Expand file tree" data-testid="expand-file-tree-button-mobile" class="prc-Button-ButtonBase-9n-Xk ExpandFileTreeButton-module__Button_1__Svs95" data-loading="false" data-size="medium" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-left" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M7.78 12.53a.75.75 0 0 1-1.06 0L2.47 8.28a.75.75 0 0 1 0-1.06l4.25-4.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042L4.81 7h7.44a.75.75 0 0 1 0 1.5H4.81l2.97 2.97a.75.75 0 0 1 0 1.06Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Files</span></span></button><button data-component="IconButton" type="button" data-testid="expand-file-tree-button" aria-controls="repos-file-tree" class="prc-Button-ButtonBase-9n-Xk position-relative ExpandFileTreeButton-module__expandButton__hDOcv ExpandFileTreeButton-module__filesButtonBreakpoint__zEvz3 fgColor-muted prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="invisible" aria-labelledby="_R_4lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-sidebar-collapse" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M6.823 7.823a.25.25 0 0 1 0 .354l-2.396 2.396A.25.25 0 0 1 4 10.396V5.604a.25.25 0 0 1 .427-.177Z"></path><path d="M1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0 1 14.25 16H1.75A1.75 1.75 0 0 1 0 14.25V1.75C0 .784.784 0 1.75 0ZM1.5 1.75v12.5c0 .138.112.25.25.25H9.5v-13H1.75a.25.25 0 0 0-.25.25ZM11 14.5h3.25a.25.25 0 0 0 .25-.25V1.75a.25.25 0 0 0-.25-.25H11Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="se" data-component="Tooltip" aria-hidden="true" id="_R_4lla9lik5_">Expand file tree</span><div class="d-none"></div></h2></div><div class="react-code-view-header-mb--narrow mr-2"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="master branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector-wide"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">master</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="react-code-view-header-mb--narrow CodeViewHeader-module__Box_5__MQ0hL"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__lg__Rjz0A"><nav data-testid="breadcrumbs" aria-labelledby="repos-header-breadcrumb-heading" id="repos-header-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="repos-header-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/firebase/FirebaseUI-Android/tree/master" data-discover="true">FirebaseUI-Android</a></li><li class="Breadcrumb-module__listItem__Ib0x_"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__lg__Rjz0A" aria-hidden="true">/</span><a class="Breadcrumb-module__directoryLink__kQy_t prc-Link-Link-9ZwDx" data-component="Link" href="/firebase/FirebaseUI-Android/tree/master/database" data-discover="true">database</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__lg__Rjz0A" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__lg__Rjz0A prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="file-name-id">README.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lla9lik5_">Copy path</span></div></div></div><div class="react-code-view-header-element--wide"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><div><div class="CodeViewHeader-module__FileResultsList__JDzUy"><span class="d-flex FileResultsList-module__FilesSearchBox__ivVkc TextInput-wrapper prc-components-TextInputWrapper-Hpdqi prc-components-TextInputBaseWrapper-wY-n0" data-no-trailing-action="true" data-component="TextInput" data-leading-visual="true" data-trailing-visual="true" aria-busy="false"><span class="TextInput-icon" id="_R_5ipla9lik5_" aria-hidden="true" data-component="TextInput.LeadingVisual"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-search" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M10.68 11.74a6 6 0 0 1-7.922-8.982 6 6 0 0 1 8.982 7.922l3.04 3.04a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215ZM11.5 7a4.499 4.499 0 1 0-8.997 0A4.499 4.499 0 0 0 11.5 7Z"></path></svg></span><input type="text" aria-label="Go to file" role="combobox" aria-controls="file-results-list" aria-expanded="false" aria-haspopup="dialog" autoCorrect="off" spellCheck="false" placeholder="Go to file" aria-describedby="_R_5ipla9lik5_ _R_5ipla9lik5H1_" data-component="input" class="prc-components-Input-IwWrt" value=""/><span class="TextInput-icon" id="_R_5ipla9lik5H1_" aria-hidden="true" data-component="TextInput.TrailingVisual"></span></span></div><div class="d-none"></div></div><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-wide" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_v4pla9lik5_" id="_R_14pla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_v4pla9lik5_">More file actions</span></div></div></div><div class="react-code-view-header-element--narrow"><div class="CodeViewHeader-module__Box_7___0R6c"><div class="d-flex gap-2"><button data-component="Button" type="button" style="display:none" class="prc-Button-ButtonBase-9n-Xk NavigationMenu-module__Button__LpKgm" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Blame</span></span></button><div class="d-none"></div><button data-component="IconButton" type="button" data-testid="more-file-actions-button-nav-menu-narrow" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click NavigationMenu-module__IconButton__HpX3G prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="medium" data-variant="default" aria-labelledby="_R_v4tla9lik5_" id="_R_14tla9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_v4tla9lik5_">More file actions</span></div></div></div></div></div></div></div><div class="CodeView-module__contentWrapper__cG2JH"><div class="react-code-view-bottom-padding"><div class="BlobTopBanners-module__Box__v_nvx"></div></div> <div class="d-none"></div><div class="d-flex flex-column border rounded-2 tmp-mb-3 pl-1"><div class="LatestCommit-module__Box__B25ZT"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">Latest commit</h2><div style="width:120px" class="Skeleton Skeleton--text" data-testid="loading"> </div><div class="d-flex flex-shrink-0 gap-2"><div data-testid="latest-commit-details" class="d-none d-sm-flex flex-items-center"></div><div class="d-flex gap-2"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">History</h2><a data-component="LinkButton" href="/firebase/FirebaseUI-Android/commits/master/database/README.md" class="prc-Button-ButtonBase-9n-Xk d-none d-lg-flex LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><span class="fgColor-default">History</span></span></span></a><div class="d-sm-none"></div><div class="d-flex d-lg-none"><a data-component="LinkButton" aria-label="View commit history for this file." href="/firebase/FirebaseUI-Android/commits/master/database/README.md" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov flex-items-center fgColor-default" data-loading="false" data-size="small" data-variant="invisible" aria-describedby="_R_4mlala9lik5_"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-history" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m.427 1.927 1.215 1.215a8.002 8.002 0 1 1-1.6 5.685.75.75 0 1 1 1.493-.154 6.5 6.5 0 1 0 1.18-4.458l1.358 1.358A.25.25 0 0 1 3.896 6H.25A.25.25 0 0 1 0 5.75V2.104a.25.25 0 0 1 .427-.177ZM7.75 4a.75.75 0 0 1 .75.75v2.992l2.028.812a.75.75 0 0 1-.557 1.392l-2.5-1A.751.751 0 0 1 7 8.25v-3.5A.75.75 0 0 1 7.75 4Z"></path></svg></span></span></a><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" role="tooltip" aria-hidden="true" id="_R_4mlala9lik5_">History</span></div></div></div></div></div><div class="d-flex flex-row"><div class="container BlobViewContent-module__blobContainer__DtH2d"><div class="react-code-size-details-banner BlobViewContent-module__codeSizeDetails__e5sUw"><div class="react-code-size-details-banner CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="17.3 KB" style="--truncate-max-width:100%"><span>522 lines (412 loc) · 17.3 KB</span></div></div></div></div><div class="react-blob-view-header-sticky BlobViewContent-module__stickyHeader__VwxB5" id="repos-sticky-header"><div class="BlobViewHeader-module__Box__yhm9u"><div class="react-blob-sticky-header"><div class="FileNameStickyHeader-module__outerWrapper__ZL4Xc FileNameStickyHeader-module__outerWrapperHidden__Zpynk"><div class="FileNameStickyHeader-module__Box_1__Hazu5"><div class="FileNameStickyHeader-module__Box_2__hoolP"><div class="FileNameStickyHeader-module__Box_3__MVKsk"><button data-component="Button" type="button" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-label="master branch" data-testid="anchor-button" data-icv-name="Switch branches/tags" class="prc-Button-ButtonBase-9n-Xk ref-selector-class RefSelectorAnchoredOverlay-module__RefSelectorOverlayBtn__a3WK3" data-loading="false" data-size="medium" data-variant="default" id="ref-picker-repos-header-ref-selector"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-git-branch" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M9.5 3.25a2.25 2.25 0 1 1 3 2.122V6A2.5 2.5 0 0 1 10 8.5H6a1 1 0 0 0-1 1v1.128a2.251 2.251 0 1 1-1.5 0V5.372a2.25 2.25 0 1 1 1.5 0v1.836A2.493 2.493 0 0 1 6 7h4a1 1 0 0 0 1-1v-.628A2.25 2.25 0 0 1 9.5 3.25Zm-6 0a.75.75 0 1 0 1.5 0 .75.75 0 0 0-1.5 0Zm8.25-.75a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5ZM4.25 12a.75.75 0 1 0 0 1.5.75.75 0 0 0 0-1.5Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3"><div class="RefSelectorAnchoredOverlay-module__RefSelectorOverlayContainer__yaf4p"><div style="max-width:125px" class="ref-selector-button-text-container RefSelectorAnchoredOverlay-module__RefSelectorBtnTextContainer__Di3rk"><span class="RefSelectorAnchoredOverlay-module__RefSelectorText__w_fmP">master</span></div></div></span><span data-component="trailingVisual" class="prc-Button-Visual-YNt2F prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-triangle-down" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="m4.427 7.427 3.396 3.396a.25.25 0 0 0 .354 0l3.396-3.396A.25.25 0 0 0 11.396 7H4.604a.25.25 0 0 0-.177.427Z"></path></svg></span></span></button><div class="d-none"></div></div><div class="FileNameStickyHeader-module__Box_4__FLhtt"><div class="Breadcrumb-module__container__Vxvev Breadcrumb-module__md__Wb1Gs"><nav data-testid="breadcrumbs" aria-labelledby="sticky-breadcrumb-heading" id="sticky-breadcrumb" class="Breadcrumb-module__nav__rQFDj"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading" id="sticky-breadcrumb-heading">Breadcrumbs</h2><ol class="Breadcrumb-module__list__ZH6zr"><li class="Breadcrumb-module__listItem__Ib0x_"><a class="Breadcrumb-module__repoLink__O2Nbs prc-Link-Link-9ZwDx" data-component="Link" data-testid="breadcrumbs-repo-link" href="/firebase/FirebaseUI-Android/tree/master" data-discover="true">FirebaseUI-Android</a></li><li class="Breadcrumb-module__listItem__Ib0x_"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__md__Wb1Gs" aria-hidden="true">/</span><a class="Breadcrumb-module__directoryLink__kQy_t prc-Link-Link-9ZwDx" data-component="Link" href="/firebase/FirebaseUI-Android/tree/master/database" data-discover="true">database</a></li></ol></nav><div data-testid="breadcrumbs-filename" class="Breadcrumb-module__filename__equZR"><span class="Breadcrumb-module__separator__eNwsI Breadcrumb-module__md__Wb1Gs" aria-hidden="true">/</span><h1 class="Breadcrumb-module__filenameHeading__MNMtw Breadcrumb-module__md__Wb1Gs prc-Heading-Heading-MtWFE" data-component="Heading" tabindex="-1" id="sticky-file-name-id">README.md</h1></div><button data-component="IconButton" type="button" class="prc-Button-ButtonBase-9n-Xk ml-2 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_7lcpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="CopyToClipboardIconButton-module__tooltip__WyiwL prc-TooltipV2-Tooltip-tLeuB" data-direction="s" data-component="Tooltip" aria-label="Copy path" aria-hidden="true" id="_R_7lcpala9lik5_">Copy path</span></div></div></div><button data-component="Button" type="button" class="prc-Button-ButtonBase-9n-Xk FileNameStickyHeader-module__Button__LSEU_ FileNameStickyHeader-module__GoToTopButton__nxAFn" data-loading="false" data-size="small" data-variant="invisible"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="leadingVisual" class="prc-Button-Visual-YNt2F prc-Button-LeadingVisual-UySKu prc-Button-VisualWrap-E4cnq"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-arrow-up" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M3.47 7.78a.75.75 0 0 1 0-1.06l4.25-4.25a.75.75 0 0 1 1.06 0l4.25 4.25a.751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018L9 4.81v7.44a.75.75 0 0 1-1.5 0V4.81L4.53 7.78a.75.75 0 0 1-1.06 0Z"></path></svg></span><span data-component="text" class="prc-Button-Label-FWkx3">Top</span></span></button></div></div></div><div class="BlobViewHeader-module__Box_1__VEmuQ"><h2 class="sr-only ScreenReaderHeading-module__userSelectNone__rwWIk prc-Heading-Heading-MtWFE" data-component="Heading" data-testid="screen-reader-heading">File metadata and controls</h2><div class="BlobViewHeader-module__Box_2__icUs2"><ul aria-label="File view" class="prc-SegmentedControl-SegmentedControl-lqIXp BlobTabButtons-module__SegmentedControl__jen2u" data-variant="default" data-size="small" data-component="SegmentedControl"><li class="prc-SegmentedControl-Item-tSCQh" data-selected="" data-component="SegmentedControl.Button"><button aria-pressed="true" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:transparent"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Preview">Preview</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Code">Code</div></span></button></li><li class="prc-SegmentedControl-Item-tSCQh" data-component="SegmentedControl.Button"><button aria-pressed="false" class="prc-SegmentedControl-Button-E48xz" type="button" style="--separator-color:var(--borderColor-default)"><span class="prc-SegmentedControl-Content-1COlk segmentedControl-content"><div class="prc-SegmentedControl-Text-7S2y2 segmentedControl-text" data-text="Blame">Blame</div></span></button></li></ul><div class="d-none"></div><div class="react-code-size-details-in-header CodeSizeDetails-module__Box__VcD6l"><div class="text-mono CodeSizeDetails-module__Box_1__GVxQL"><div data-testid="blob-size" class="CodeSizeDetails-module__Truncate_1__lE93V prc-Truncate-Truncate-2G1eo" data-inline="true" title="17.3 KB" style="--truncate-max-width:100%"><span>522 lines (412 loc) · 17.3 KB</span></div></div></div></div><div class="BlobViewHeader-module__Box_3__ng6v2"><div class="d-none"></div><div class="react-blob-header-edit-and-raw-actions BlobViewHeader-module__Box_4__J4Y4W"><div class="d-none"></div><div class="prc-ButtonGroup-ButtonGroup-vFUrY" data-component="ButtonGroup"><div class="prc-ButtonGroup-Item-PqvDl"><a data-component="LinkButton" href="https://github.com/firebase/FirebaseUI-Android/raw/refs/heads/master/database/README.md" data-testid="raw-button" class="prc-Button-ButtonBase-9n-Xk LinkButton-module__linkButton__nFnov BlobViewHeader-module__LinkButton__X9kx2" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default"><span data-component="buttonContent" data-align="center" class="prc-Button-ButtonContent-Iohp5"><span data-component="text" class="prc-Button-Label-FWkx3">Raw</span></span></a></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="copy-raw-button" class="prc-Button-ButtonBase-9n-Xk prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_qaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-copy" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_qaucpala9lik5_">Copy raw file</span></div><div class="prc-ButtonGroup-Item-PqvDl"><button data-component="IconButton" type="button" data-testid="download-raw-button" class="prc-Button-ButtonBase-9n-Xk BlobViewHeader-module__downloadButton__ef459 prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="default" aria-labelledby="_R_eaucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-download" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M2.75 14A1.75 1.75 0 0 1 1 12.25v-2.5a.75.75 0 0 1 1.5 0v2.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25v-2.5a.75.75 0 0 1 1.5 0v2.5A1.75 1.75 0 0 1 13.25 14Z"></path><path d="M7.25 7.689V2a.75.75 0 0 1 1.5 0v5.689l1.97-1.969a.749.749 0 1 1 1.06 1.06l-3.25 3.25a.749.749 0 0 1-1.06 0L4.22 6.78a.749.749 0 1 1 1.06-1.06l1.97 1.969Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_eaucpala9lik5_">Download raw file</span></div></div></div><button data-component="IconButton" type="button" aria-pressed="false" class="prc-Button-ButtonBase-9n-Xk tmp-mr-2 TableOfContents-module__IconButton__jrlNM prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_3ucpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-list-unordered" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M5.75 2.5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5Zm0 5h8.5a.75.75 0 0 1 0 1.5h-8.5a.75.75 0 0 1 0-1.5ZM2 14a1 1 0 1 1 0-2 1 1 0 0 1 0 2Zm1-6a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM2 4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="n" data-component="Tooltip" aria-hidden="true" id="_R_3ucpala9lik5_">Outline</span><div class="react-blob-header-edit-and-raw-actions-combined"><button data-component="IconButton" type="button" title="More file actions" data-testid="more-file-actions-button" aria-haspopup="true" aria-expanded="false" tabindex="0" class="prc-Button-ButtonBase-9n-Xk js-blob-dropdown-click BlobViewHeader-module__IconButton__XrMQY prc-Button-IconButton-fyge7" data-loading="false" data-no-visuals="true" data-size="small" data-variant="invisible" aria-labelledby="_R_fkecpala9lik5_" id="_R_kecpala9lik5_"><svg data-component="Octicon" aria-hidden="true" focusable="false" class="octicon octicon-kebab-horizontal" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" display="inline-block" overflow="visible" style="vertical-align:text-bottom"><path d="M8 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM1.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm13 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z"></path></svg></button><span class="prc-TooltipV2-Tooltip-tLeuB" data-direction="nw" data-component="Tooltip" aria-hidden="true" id="_R_fkecpala9lik5_">Edit and raw actions</span></div></div></div></div><div></div></div><div class="BlobViewContent-module__blobContentWrapper__JS0W6"><section aria-labelledby="file-name-id-wide file-name-id-mobile" class="BlobContent-module__blobContentSection__VOgZq BlobContent-module__blobContentSectionMarkdown__mPLOK" style="margin-top:46px"><div class="js-snippet-clipboard-copy-unpositioned BlobContent-module__markdownBlob__T8jpG" data-hpc="true" containertiming="hpc"><article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h1 tabindex="-1" class="heading-element" dir="auto">FirebaseUI for Realtime Database</h1><a id="user-content-firebaseui-for-realtime-database" class="anchor" aria-label="Permalink: FirebaseUI for Realtime Database" href="#firebaseui-for-realtime-database"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">FirebaseUI makes it simple to bind data from the Firebase Realtime Database to your app's UI.</p>
<p dir="auto">Before using this library, you should be familiar with the following topics:</p>
<ul dir="auto">
<li><a href="https://firebase.google.com/docs/database/android/lists-of-data" rel="nofollow">Working with lists of data in Firebase Realtime Database</a>.</li>
<li><a href="https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView" rel="nofollow">Displaying lists of data using a RecyclerView</a>.</li>
</ul>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Table of contents</h2><a id="user-content-table-of-contents" class="anchor" aria-label="Permalink: Table of contents" href="#table-of-contents"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<ol dir="auto">
<li><a href="#data-model">Data model</a></li>
<li><a href="#querying">Querying</a></li>
<li><a href="#using-firebaseui-to-populate-a-recyclerview">Populating a RecyclerView</a>
<ol dir="auto">
<li><a href="#using-the-firebaserecycleradapter">Using the FirebaseRecyclerAdapter</a></li>
<li><a href="#using-the-firebaserecyclerpagingadapter">Using the FirebaseRecyclerPagingAdapter</a></li>
</ol>
</li>
<li><a href="#using-firebaseui-to-populate-a-listview">Populating a ListView</a></li>
<li><a href="#using-firebaseui-with-indexed-data">Handling indexed data</a>
<ol dir="auto">
<li><a href="#a-note-on-ordering">Warnings</a></li>
</ol>
</li>
</ol>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Data model</h2><a id="user-content-data-model" class="anchor" aria-label="Permalink: Data model" href="#data-model"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Imagine you have a chat app where each chat message is an item in the <code>chats</code> node
of your database. In your app, you may represent a chat message like this:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="public class Chat {
    private String mName;
    private String mMessage;
    private String mUid;

    public Chat() {}  // Needed for Firebase

    public Chat(String name, String message, String uid) {
        mName = name;
        mMessage = message;
        mUid = uid;
    }

    public String getName() { return mName; }

    public void setName(String name) { mName = name; }

    public String getMessage() { return mMessage; }

    public void setMessage(String message) { mMessage = message; }

    public String getUid() { return mUid; }

    public void setUid(String uid) { mUid = uid; }
}"><pre><span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-smi">Chat</span> {
    <span class="pl-k">private</span> <span class="pl-smi">String</span> <span class="pl-s1">mName</span>;
    <span class="pl-k">private</span> <span class="pl-smi">String</span> <span class="pl-s1">mMessage</span>;
    <span class="pl-k">private</span> <span class="pl-smi">String</span> <span class="pl-s1">mUid</span>;

    <span class="pl-k">public</span> <span class="pl-smi">Chat</span>() {}  <span class="pl-c">// Needed for Firebase</span>

    <span class="pl-k">public</span> <span class="pl-smi">Chat</span>(<span class="pl-smi">String</span> <span class="pl-s1">name</span>, <span class="pl-smi">String</span> <span class="pl-s1">message</span>, <span class="pl-smi">String</span> <span class="pl-s1">uid</span>) {
        <span class="pl-s1">mName</span> = <span class="pl-s1">name</span>;
        <span class="pl-s1">mMessage</span> = <span class="pl-s1">message</span>;
        <span class="pl-s1">mUid</span> = <span class="pl-s1">uid</span>;
    }

    <span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getName</span>() { <span class="pl-k">return</span> <span class="pl-s1">mName</span>; }

    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">setName</span>(<span class="pl-smi">String</span> <span class="pl-s1">name</span>) { <span class="pl-s1">mName</span> = <span class="pl-s1">name</span>; }

    <span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getMessage</span>() { <span class="pl-k">return</span> <span class="pl-s1">mMessage</span>; }

    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">setMessage</span>(<span class="pl-smi">String</span> <span class="pl-s1">message</span>) { <span class="pl-s1">mMessage</span> = <span class="pl-s1">message</span>; }

    <span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getUid</span>() { <span class="pl-k">return</span> <span class="pl-s1">mUid</span>; }

    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">setUid</span>(<span class="pl-smi">String</span> <span class="pl-s1">uid</span>) { <span class="pl-s1">mUid</span> = <span class="pl-s1">uid</span>; }
}</pre></div>
<p dir="auto">A few things to note about this model class:</p>
<ul dir="auto">
<li>The getters and setters follow the JavaBean naming pattern which allows Firebase to map
the data to field names (ex: <code>getName()</code> provides the <code>name</code> field).</li>
<li>The class has an empty constructor, which is required for Firebase's automatic data mapping.</li>
</ul>
<p dir="auto">For a properly constructed model class like the <code>Chat</code> class above, Firebase can perform automatic
serialization in <code>DatabaseReference#setValue()</code> and automatic deserialization in
<code>DataSnapshot#getValue()</code>.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Querying</h3><a id="user-content-querying" class="anchor" aria-label="Permalink: Querying" href="#querying"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">On the main screen of your app, you may want to show the 50 most recent chat messages. With Firebase
you would use the following query:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="Query query = FirebaseDatabase.getInstance()
        .getReference()
        .child(&quot;chats&quot;)
        .limitToLast(50);"><pre><span class="pl-smi">Query</span> <span class="pl-s1">query</span> = <span class="pl-smi">FirebaseDatabase</span>.<span class="pl-en">getInstance</span>()
        .<span class="pl-en">getReference</span>()
        .<span class="pl-en">child</span>(<span class="pl-s">"chats"</span>)
        .<span class="pl-en">limitToLast</span>(<span class="pl-c1">50</span>);</pre></div>
<p dir="auto">To retrieve this data without FirebaseUI, you might use <code>addChildEventListener</code> to listen for
live updates:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="ChildEventListener childEventListener = new ChildEventListener() {
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
        // ...
    }

    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
        // ...
    }

    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {
        // ...
    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
        // ...
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // ...
    }
};
query.addChildEventListener(childEventListener);"><pre><span class="pl-smi">ChildEventListener</span> <span class="pl-s1">childEventListener</span> = <span class="pl-k">new</span> <span class="pl-smi">ChildEventListener</span>() {
    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">onChildAdded</span>(<span class="pl-smi">DataSnapshot</span> <span class="pl-s1">dataSnapshot</span>, <span class="pl-smi">String</span> <span class="pl-s1">previousChildName</span>) {
        <span class="pl-c">// ...</span>
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">onChildChanged</span>(<span class="pl-smi">DataSnapshot</span> <span class="pl-s1">dataSnapshot</span>, <span class="pl-smi">String</span> <span class="pl-s1">previousChildName</span>) {
        <span class="pl-c">// ...</span>
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">onChildRemoved</span>(<span class="pl-smi">DataSnapshot</span> <span class="pl-s1">dataSnapshot</span>) {
        <span class="pl-c">// ...</span>
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">onChildMoved</span>(<span class="pl-smi">DataSnapshot</span> <span class="pl-s1">dataSnapshot</span>, <span class="pl-smi">String</span> <span class="pl-s1">previousChildName</span>) {
        <span class="pl-c">// ...</span>
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">onCancelled</span>(<span class="pl-smi">DatabaseError</span> <span class="pl-s1">databaseError</span>) {
        <span class="pl-c">// ...</span>
    }
};
<span class="pl-s1">query</span>.<span class="pl-en">addChildEventListener</span>(<span class="pl-s1">childEventListener</span>);</pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Using FirebaseUI to populate a <code>RecyclerView</code></h2><a id="user-content-using-firebaseui-to-populate-a-recyclerview" class="anchor" aria-label="Permalink: Using FirebaseUI to populate a RecyclerView" href="#using-firebaseui-to-populate-a-recyclerview"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you're displaying a list of data, you likely want to bind the <code>Chat</code> objects to a <code>RecyclerView</code>.
This means implementing a custom <code>RecyclerView.Adapter</code> and coordinating updates with the
<code>ChildEventListener</code>.</p>
<p dir="auto">Fear not, FirebaseUI does all of this for you automatically!</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Choosing an adapter</h3><a id="user-content-choosing-an-adapter" class="anchor" aria-label="Permalink: Choosing an adapter" href="#choosing-an-adapter"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">FirebaseUI offers two types of RecyclerView adapters for the Realtime Database:</p>
<ul dir="auto">
<li><code>FirebaseRecyclerAdapter</code> — binds a <code>Query</code> to a <code>RecyclerView</code> and responds to all real-time
events included items being added, removed, moved, or changed. Best used with small result sets
since all results are loaded at once.</li>
<li><code>FirebaseRecyclerPagingAdapter</code> — binds a <code>Query</code> to a <code>RecyclerView</code> by loading data in pages. Best
used with large, static data sets. Real-time events are not respected by this adapter, so it
will not detect new/removed items or changes to items already loaded.</li>
</ul>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Using the FirebaseRecyclerAdapter</h3><a id="user-content-using-the-firebaserecycleradapter" class="anchor" aria-label="Permalink: Using the FirebaseRecyclerAdapter" href="#using-the-firebaserecycleradapter"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The <code>FirebaseRecyclerAdapter</code> binds a <code>Query</code> to a <code>RecyclerView</code>. When data is added, removed,
or changed these updates are automatically applied to your UI in real time.</p>
<p dir="auto">First, configure the adapter by building <code>FirebaseRecyclerOptions</code>. In this case we will continue
with our chat example:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content=" FirebaseRecyclerOptions&lt;Chat&gt; options =
                new FirebaseRecyclerOptions.Builder&lt;Chat&gt;()
                        .setQuery(query, Chat.class)
                        .build();"><pre> <span class="pl-smi">FirebaseRecyclerOptions</span>&lt;<span class="pl-smi">Chat</span>&gt; <span class="pl-s1">options</span> =
                <span class="pl-k">new</span> <span class="pl-smi">FirebaseRecyclerOptions</span>.<span class="pl-smi">Builder</span>&lt;<span class="pl-smi">Chat</span>&gt;()
                        .<span class="pl-en">setQuery</span>(<span class="pl-s1">query</span>, <span class="pl-smi">Chat</span>.<span class="pl-k">class</span>)
                        .<span class="pl-en">build</span>();</pre></div>
<p dir="auto">If you need to customize how your model class is parsed, you can use a custom <code>SnapshotParser</code>:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="...setQuery(..., new SnapshotParser&lt;Chat&gt;() {
    @NonNull
    @Override
    public Chat parseSnapshot(@NonNull DataSnapshot snapshot) {
        return ...;
    }
});"><pre>...<span class="pl-en">setQuery</span>(..., <span class="pl-k">new</span> <span class="pl-smi">SnapshotParser</span>&lt;<span class="pl-smi">Chat</span>&gt;() {
    <span class="pl-c1">@</span><span class="pl-c1">NonNull</span>
    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">Chat</span> <span class="pl-en">parseSnapshot</span>(<span class="pl-c1">@</span><span class="pl-c1">NonNull</span> <span class="pl-smi">DataSnapshot</span> <span class="pl-s1">snapshot</span>) {
        <span class="pl-k">return</span> ...;
    }
});</pre></div>
<p dir="auto">Next create the <code>FirebaseRecyclerAdapter</code> object. You should already have a <code>ViewHolder</code> subclass
for displaying each item. In this case we will use a custom <code>ChatHolder</code> class:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter&lt;Chat, ChatHolder&gt;(options) {
    @Override
    public ChatHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // Create a new instance of the ViewHolder, in this case we are using a custom
        // layout called R.layout.message for each item
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.message, parent, false);

        return new ChatHolder(view);
    }

    @Override
    protected void onBindViewHolder(ChatHolder holder, int position, Chat model) {
        // Bind the Chat object to the ChatHolder
        // ...
    }
};"><pre><span class="pl-smi">FirebaseRecyclerAdapter</span> <span class="pl-s1">adapter</span> = <span class="pl-k">new</span> <span class="pl-smi">FirebaseRecyclerAdapter</span>&lt;<span class="pl-smi">Chat</span>, <span class="pl-smi">ChatHolder</span>&gt;(<span class="pl-s1">options</span>) {
    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">ChatHolder</span> <span class="pl-en">onCreateViewHolder</span>(<span class="pl-smi">ViewGroup</span> <span class="pl-s1">parent</span>, <span class="pl-smi">int</span> <span class="pl-s1">viewType</span>) {
        <span class="pl-c">// Create a new instance of the ViewHolder, in this case we are using a custom</span>
        <span class="pl-c">// layout called R.layout.message for each item</span>
        <span class="pl-smi">View</span> <span class="pl-s1">view</span> = <span class="pl-smi">LayoutInflater</span>.<span class="pl-en">from</span>(<span class="pl-s1">parent</span>.<span class="pl-en">getContext</span>())
                .<span class="pl-en">inflate</span>(<span class="pl-smi">R</span>.<span class="pl-s1">layout</span>.<span class="pl-s1">message</span>, <span class="pl-s1">parent</span>, <span class="pl-c1">false</span>);

        <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">ChatHolder</span>(<span class="pl-s1">view</span>);
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">protected</span> <span class="pl-smi">void</span> <span class="pl-en">onBindViewHolder</span>(<span class="pl-smi">ChatHolder</span> <span class="pl-s1">holder</span>, <span class="pl-smi">int</span> <span class="pl-s1">position</span>, <span class="pl-smi">Chat</span> <span class="pl-s1">model</span>) {
        <span class="pl-c">// Bind the Chat object to the ChatHolder</span>
        <span class="pl-c">// ...</span>
    }
};</pre></div>
<p dir="auto">Finally attach the adapter to your <code>RecyclerView</code> with the <code>RecyclerView#setAdapter()</code> method.
Don't forget to also set a <code>LayoutManager</code>!</p>
<div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">FirebaseRecyclerAdapter lifecycle</h4><a id="user-content-firebaserecycleradapter-lifecycle" class="anchor" aria-label="Permalink: FirebaseRecyclerAdapter lifecycle" href="#firebaserecycleradapter-lifecycle"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Start/stop listening</h5><a id="user-content-startstop-listening" class="anchor" aria-label="Permalink: Start/stop listening" href="#startstop-listening"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The <code>FirebaseRecyclerAdapter</code> uses an event listener to monitor changes to the Firebase query.
To begin listening for data, call the <code>startListening()</code> method. You may want to call this in your
<code>onStart()</code> method. Make sure you have finished any authentication necessary to read the data
before calling <code>startListening()</code> or your query will fail.</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Override
protected void onStart() {
    super.onStart();
    adapter.startListening();
}"><pre><span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">protected</span> <span class="pl-smi">void</span> <span class="pl-en">onStart</span>() {
    <span class="pl-en">super</span>.<span class="pl-en">onStart</span>();
    <span class="pl-s1">adapter</span>.<span class="pl-en">startListening</span>();
}</pre></div>
<p dir="auto">Similarly, the <code>stopListening()</code> call removes the event  listener and all data in the adapter.
Call this method when the containing Activity or Fragment stops:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Override
protected void onStop() {
    super.onStop();
    adapter.stopListening();
}"><pre><span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">protected</span> <span class="pl-smi">void</span> <span class="pl-en">onStop</span>() {
    <span class="pl-en">super</span>.<span class="pl-en">onStop</span>();
    <span class="pl-s1">adapter</span>.<span class="pl-en">stopListening</span>();
}</pre></div>
<div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Automatic listening</h5><a id="user-content-automatic-listening" class="anchor" aria-label="Permalink: Automatic listening" href="#automatic-listening"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you don't want to manually start/stop listening you can use
<a href="https://developer.android.com/topic/libraries/architecture/index.html" rel="nofollow">Android Architecture Components</a> to automatically manage the lifecycle of the
<code>FirebaseRecyclerAdapter</code>. Pass a <code>LifecycleOwner</code> to
<code>FirebaseRecyclerOptions.Builder#setLifecycleOwner(...)</code> and FirebaseUI will automatically
start and stop listening in <code>onStart()</code> and <code>onStop()</code>.</p>
<div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Data and error events</h4><a id="user-content-data-and-error-events" class="anchor" aria-label="Permalink: Data and error events" href="#data-and-error-events"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">When using the <code>FirebaseRecyclerAdapter</code> you may want to perform some action every time data
changes or when there is an error. To do this, override the <code>onDataChanged()</code> and <code>onError()</code>
methods of the adapter:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter&lt;Chat, ChatHolder&gt;(options) {
    // ...

    @Override
    public void onDataChanged() {
        // Called each time there is a new data snapshot. You may want to use this method
        // to hide a loading spinner or check for the &quot;no documents&quot; state and update your UI.
        // ...
    }

    @Override
    public void onError(DatabaseError e) {
        // Called when there is an error getting data. You may want to update
        // your UI to display an error message to the user.
        // ...
    }
};"><pre><span class="pl-smi">FirebaseRecyclerAdapter</span> <span class="pl-s1">adapter</span> = <span class="pl-k">new</span> <span class="pl-smi">FirebaseRecyclerAdapter</span>&lt;<span class="pl-smi">Chat</span>, <span class="pl-smi">ChatHolder</span>&gt;(<span class="pl-s1">options</span>) {
    <span class="pl-c">// ...</span>

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">onDataChanged</span>() {
        <span class="pl-c">// Called each time there is a new data snapshot. You may want to use this method</span>
        <span class="pl-c">// to hide a loading spinner or check for the "no documents" state and update your UI.</span>
        <span class="pl-c">// ...</span>
    }

    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-en">onError</span>(<span class="pl-smi">DatabaseError</span> <span class="pl-s1">e</span>) {
        <span class="pl-c">// Called when there is an error getting data. You may want to update</span>
        <span class="pl-c">// your UI to display an error message to the user.</span>
        <span class="pl-c">// ...</span>
    }
};</pre></div>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">Using the <code>FirebaseRecyclerPagingAdapter</code></h3><a id="user-content-using-the-firebaserecyclerpagingadapter" class="anchor" aria-label="Permalink: Using the FirebaseRecyclerPagingAdapter" href="#using-the-firebaserecyclerpagingadapter"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The <code>FirebaseRecyclerPagingAdapter</code> binds a <code>Query</code> to a <code>RecyclerView</code> by loading documents in pages.
This results in a time and memory efficient binding, however it gives up the real-time events
afforded by the <code>FirebaseRecyclerAdapter</code>.</p>
<p dir="auto">The <code>FirebaseRecyclerPagingAdapter</code> is built on top of the <a href="https://developer.android.com/topic/libraries/architecture/paging/v3-overview" rel="nofollow">Android Paging 3 Library</a>.
Before using the adapter in your application, you must add a dependency on that library:</p>
<div class="highlight highlight-source-groovy notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="implementation 'androidx.paging:paging-runtime:3.x.x'"><pre>implementation <span class="pl-s"><span class="pl-pds">'</span>androidx.paging:paging-runtime:3.x.x<span class="pl-pds">'</span></span></pre></div>
<p dir="auto">First, configure the adapter by building <code>DatabasePagingOptions</code>. Since the paging adapter
is not appropriate for a chat application (it would not detect new messages), we will consider
an adapter that loads a generic <code>Item</code>:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// The &quot;base query&quot; is a query with no startAt/endAt/limit clauses that the adapter can use
// to form smaller queries for each page.
Query baseQuery = mDatabase.getReference().child(&quot;items&quot;);

// This configuration comes from the Paging 3 Library
// https://developer.android.com/reference/kotlin/androidx/paging/PagingConfig
PagingConfig config = new PagingConfig(/* page size */ 20, /* prefetchDistance */ 10,
    /* enablePlaceHolders */ false);

// The options for the adapter combine the paging configuration with query information
// and application-specific options for lifecycle, etc.
DatabasePagingOptions&lt;Item&gt; options = new DatabasePagingOptions.Builder&lt;Item&gt;()
        .setLifecycleOwner(this)
        .setQuery(baseQuery, config, Item.class)
        .build();"><pre><span class="pl-c">// The "base query" is a query with no startAt/endAt/limit clauses that the adapter can use</span>
<span class="pl-c">// to form smaller queries for each page.</span>
<span class="pl-smi">Query</span> <span class="pl-s1">baseQuery</span> = <span class="pl-s1">mDatabase</span>.<span class="pl-en">getReference</span>().<span class="pl-en">child</span>(<span class="pl-s">"items"</span>);

<span class="pl-c">// This configuration comes from the Paging 3 Library</span>
<span class="pl-c">// https://developer.android.com/reference/kotlin/androidx/paging/PagingConfig</span>
<span class="pl-smi">PagingConfig</span> <span class="pl-s1">config</span> = <span class="pl-k">new</span> <span class="pl-smi">PagingConfig</span>(<span class="pl-c">/* page size */</span> <span class="pl-c1">20</span>, <span class="pl-c">/* prefetchDistance */</span> <span class="pl-c1">10</span>,
    <span class="pl-c">/* enablePlaceHolders */</span> <span class="pl-c1">false</span>);

<span class="pl-c">// The options for the adapter combine the paging configuration with query information</span>
<span class="pl-c">// and application-specific options for lifecycle, etc.</span>
<span class="pl-smi">DatabasePagingOptions</span>&lt;<span class="pl-smi">Item</span>&gt; <span class="pl-s1">options</span> = <span class="pl-k">new</span> <span class="pl-smi">DatabasePagingOptions</span>.<span class="pl-smi">Builder</span>&lt;<span class="pl-smi">Item</span>&gt;()
        .<span class="pl-en">setLifecycleOwner</span>(<span class="pl-smi">this</span>)
        .<span class="pl-en">setQuery</span>(<span class="pl-s1">baseQuery</span>, <span class="pl-s1">config</span>, <span class="pl-smi">Item</span>.<span class="pl-k">class</span>)
        .<span class="pl-en">build</span>();</pre></div>
<p dir="auto">If you need to customize how your model class is parsed, you can use a custom <code>SnapshotParser</code>:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="...setQuery(..., new SnapshotParser&lt;Item&gt;() {
    @NonNull
    @Override
    public Item parseSnapshot(@NonNull DocumentSnapshot snapshot) {
        return ...;
    }
});"><pre>...<span class="pl-en">setQuery</span>(..., <span class="pl-k">new</span> <span class="pl-smi">SnapshotParser</span>&lt;<span class="pl-smi">Item</span>&gt;() {
    <span class="pl-c1">@</span><span class="pl-c1">NonNull</span>
    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">Item</span> <span class="pl-en">parseSnapshot</span>(<span class="pl-c1">@</span><span class="pl-c1">NonNull</span> <span class="pl-smi">DocumentSnapshot</span> <span class="pl-s1">snapshot</span>) {
        <span class="pl-k">return</span> ...;
    }
});</pre></div>
<p dir="auto">Next, create the <code>FirebaseRecyclerPagingAdapter</code> object. You should already have a <code>ViewHolder</code> subclass
for displaying each item. In this case we will use a custom <code>ItemViewHolder</code> class:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="FirebaseRecyclerPagingAdapter&lt;Item, ItemViewHolder&gt; adapter =
        new FirebaseRecyclerPagingAdapter&lt;Item, ItemViewHolder&gt;(options) {
            @NonNull
            @Override
            public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                // Create the ItemViewHolder
                // ...
            }

            @Override
            protected void onBindViewHolder(@NonNull ItemViewHolder holder,
                                            int position,
                                            @NonNull Item model) {
                // Bind the item to the view holder
                // ...
            }
        };"><pre><span class="pl-smi">FirebaseRecyclerPagingAdapter</span>&lt;<span class="pl-smi">Item</span>, <span class="pl-smi">ItemViewHolder</span>&gt; <span class="pl-s1">adapter</span> =
        <span class="pl-k">new</span> <span class="pl-smi">FirebaseRecyclerPagingAdapter</span>&lt;<span class="pl-smi">Item</span>, <span class="pl-smi">ItemViewHolder</span>&gt;(<span class="pl-s1">options</span>) {
            <span class="pl-c1">@</span><span class="pl-c1">NonNull</span>
            <span class="pl-c1">@</span><span class="pl-c1">Override</span>
            <span class="pl-k">public</span> <span class="pl-smi">ItemViewHolder</span> <span class="pl-en">onCreateViewHolder</span>(<span class="pl-c1">@</span><span class="pl-c1">NonNull</span> <span class="pl-smi">ViewGroup</span> <span class="pl-s1">parent</span>, <span class="pl-smi">int</span> <span class="pl-s1">viewType</span>) {
                <span class="pl-c">// Create the ItemViewHolder</span>
                <span class="pl-c">// ...</span>
            }

            <span class="pl-c1">@</span><span class="pl-c1">Override</span>
            <span class="pl-k">protected</span> <span class="pl-smi">void</span> <span class="pl-en">onBindViewHolder</span>(<span class="pl-c1">@</span><span class="pl-c1">NonNull</span> <span class="pl-smi">ItemViewHolder</span> <span class="pl-s1">holder</span>,
                                            <span class="pl-smi">int</span> <span class="pl-s1">position</span>,
                                            <span class="pl-c1">@</span><span class="pl-c1">NonNull</span> <span class="pl-smi">Item</span> <span class="pl-s1">model</span>) {
                <span class="pl-c">// Bind the item to the view holder</span>
                <span class="pl-c">// ...</span>
            }
        };</pre></div>
<p dir="auto">Finally attach the adapter to your <code>RecyclerView</code> with the <code>RecyclerView#setAdapter()</code> method.
Don't forget to also set a <code>LayoutManager</code>!</p>
<div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto"><code>FirebaseRecyclerPagingAdapter</code> lifecycle</h4><a id="user-content-firebaserecyclerpagingadapter-lifecycle" class="anchor" aria-label="Permalink: FirebaseRecyclerPagingAdapter lifecycle" href="#firebaserecyclerpagingadapter-lifecycle"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Start/stop listening</h5><a id="user-content-startstop-listening-1" class="anchor" aria-label="Permalink: Start/stop listening" href="#startstop-listening-1"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The <code>FirebaseRecyclerPagingAdapter</code> listens for scrolling events and loads additional pages from the
database only when needed.</p>
<p dir="auto">To begin populating data, call the <code>startListening()</code> method. You may want to call this
in your <code>onStart()</code> method. Make sure you have finished any authentication necessary to read the
data before calling <code>startListening()</code> or your query will fail.</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Override
protected void onStart() {
    super.onStart();
    adapter.startListening();
}"><pre><span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">protected</span> <span class="pl-smi">void</span> <span class="pl-en">onStart</span>() {
    <span class="pl-en">super</span>.<span class="pl-en">onStart</span>();
    <span class="pl-s1">adapter</span>.<span class="pl-en">startListening</span>();
}</pre></div>
<p dir="auto">Similarly, the <code>stopListening()</code> call freezes the data in the <code>RecyclerView</code> and prevents any future
loading of data pages.</p>
<p dir="auto">Call this method when the containing Activity or Fragment stops:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Override
protected void onStop() {
    super.onStop();
    adapter.stopListening();
}"><pre><span class="pl-c1">@</span><span class="pl-c1">Override</span>
<span class="pl-k">protected</span> <span class="pl-smi">void</span> <span class="pl-en">onStop</span>() {
    <span class="pl-en">super</span>.<span class="pl-en">onStop</span>();
    <span class="pl-s1">adapter</span>.<span class="pl-en">stopListening</span>();
}</pre></div>
<div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">Automatic listening</h5><a id="user-content-automatic-listening-1" class="anchor" aria-label="Permalink: Automatic listening" href="#automatic-listening-1"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If you don't want to manually start/stop listening you can use
<a href="https://developer.android.com/topic/libraries/architecture/index.html" rel="nofollow">Android Architecture Components</a> to automatically manage the lifecycle of the
<code>FirebaseRecyclerPagingAdapter</code>. Pass a <code>LifecycleOwner</code> to
<code>DatabasePagingOptions.Builder#setLifecycleOwner(...)</code> and FirebaseUI will automatically
start and stop listening in <code>onStart()</code> and <code>onStop()</code>.</p>
<div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">Paging events</h4><a id="user-content-paging-events" class="anchor" aria-label="Permalink: Paging events" href="#paging-events"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">When using the <code>FirebaseRecyclerPagingAdapter</code>, you may want to perform some action every time data
changes or when there is an error. To do this:</p>
<div class="markdown-heading" dir="auto"><h5 tabindex="-1" class="heading-element" dir="auto">In Java</h5><a id="user-content-in-java" class="anchor" aria-label="Permalink: In Java" href="#in-java"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use the <code>addLoadStateListener</code> method from the adapter:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="adapter.addLoadStateListener(new Function1&lt;CombinedLoadStates, Unit&gt;() {
            @Override
            public Unit invoke(CombinedLoadStates states) {
                LoadState refresh = states.getRefresh();
                LoadState append = states.getAppend();

                if (refresh instanceof LoadState.Error || append instanceof LoadState.Error) {
                    // The previous load (either initial or additional) failed. Call
                    // the retry() method in order to retry the load operation.
                    // ...
                }

                if (refresh instanceof LoadState.Loading) {
                    // The initial Load has begun
                    // ...
                }

                if (append instanceof LoadState.Loading) {
                    // The adapter has started to load an additional page
                    // ...
                }

                if (append instanceof LoadState.NotLoading) {
                    LoadState.NotLoading notLoading = (LoadState.NotLoading) append;
                    if (notLoading.getEndOfPaginationReached()) {
                        // The adapter has finished loading all of the data set
                        // ...
                        return null;
                    }

                    if (refresh instanceof LoadState.NotLoading) {
                        // The previous load (either initial or additional) completed
                        // ...
                        return null;
                    }
                }
                return null;
            }
        });"><pre><span class="pl-s1">adapter</span>.<span class="pl-en">addLoadStateListener</span>(<span class="pl-k">new</span> <span class="pl-smi">Function1</span>&lt;<span class="pl-smi">CombinedLoadStates</span>, <span class="pl-smi">Unit</span>&gt;() {
            <span class="pl-c1">@</span><span class="pl-c1">Override</span>
            <span class="pl-k">public</span> <span class="pl-smi">Unit</span> <span class="pl-en">invoke</span>(<span class="pl-smi">CombinedLoadStates</span> <span class="pl-s1">states</span>) {
                <span class="pl-smi">LoadState</span> <span class="pl-s1">refresh</span> = <span class="pl-s1">states</span>.<span class="pl-en">getRefresh</span>();
                <span class="pl-smi">LoadState</span> <span class="pl-s1">append</span> = <span class="pl-s1">states</span>.<span class="pl-en">getAppend</span>();

                <span class="pl-k">if</span> (<span class="pl-s1">refresh</span> <span class="pl-k">instanceof</span> <span class="pl-smi">LoadState</span>.<span class="pl-smi">Error</span> || <span class="pl-s1">append</span> <span class="pl-k">instanceof</span> <span class="pl-smi">LoadState</span>.<span class="pl-smi">Error</span>) {
                    <span class="pl-c">// The previous load (either initial or additional) failed. Call</span>
                    <span class="pl-c">// the retry() method in order to retry the load operation.</span>
                    <span class="pl-c">// ...</span>
                }

                <span class="pl-k">if</span> (<span class="pl-s1">refresh</span> <span class="pl-k">instanceof</span> <span class="pl-smi">LoadState</span>.<span class="pl-smi">Loading</span>) {
                    <span class="pl-c">// The initial Load has begun</span>
                    <span class="pl-c">// ...</span>
                }

                <span class="pl-k">if</span> (<span class="pl-s1">append</span> <span class="pl-k">instanceof</span> <span class="pl-smi">LoadState</span>.<span class="pl-smi">Loading</span>) {
                    <span class="pl-c">// The adapter has started to load an additional page</span>
                    <span class="pl-c">// ...</span>
                }

                <span class="pl-k">if</span> (<span class="pl-s1">append</span> <span class="pl-k">instanceof</span> <span class="pl-smi">LoadState</span>.<span class="pl-smi">NotLoading</span>) {
                    <span class="pl-smi">LoadState</span>.<span class="pl-smi">NotLoading</span> <span class="pl-s1">notLoading</span> = (<span class="pl-smi">LoadState</span>.<span class="pl-smi">NotLoading</span>) <span class="pl-s1">append</span>;
                    <span class="pl-k">if</span> (<span class="pl-s1">notLoading</span>.<span class="pl-en">getEndOfPaginationReached</span>()) {
                        <span class="pl-c">// The adapter has finished loading all of the data set</span>
                        <span class="pl-c">// ...</span>
                        <span class="pl-k">return</span> <span class="pl-c1">null</span>;
                    }

                    <span class="pl-k">if</span> (<span class="pl-s1">refresh</span> <span class="pl-k">instanceof</span> <span class="pl-smi">LoadState</span>.<span class="pl-smi">NotLoading</span>) {
                        <span class="pl-c">// The previous load (either initial or additional) completed</span>
                        <span class="pl-c">// ...</span>
                        <span class="pl-k">return</span> <span class="pl-c1">null</span>;
                    }
                }
                <span class="pl-k">return</span> <span class="pl-c1">null</span>;
            }
        });</pre></div>
<div class="markdown-heading" dir="auto"><h4 tabindex="-1" class="heading-element" dir="auto">In Kotlin</h4><a id="user-content-in-kotlin" class="anchor" aria-label="Permalink: In Kotlin" href="#in-kotlin"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">Use the <code>loadStateFlow</code> exposed by the adapter, in a Coroutine Scope:</p>
<div class="highlight highlight-source-kotlin notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// Activities can use lifecycleScope directly, but Fragments should instead use
// viewLifecycleOwner.lifecycleScope.
lifecycleScope.launch {
    pagingAdapter.loadStateFlow.collectLatest { loadStates -&gt;
        when (loadStates.refresh) {
            is LoadState.Error -&gt; {
                // The initial load failed. Call the retry() method
                // in order to retry the load operation.
                // ...
            }
            is LoadState.Loading -&gt; {
                // The initial Load has begun
                // ...
            }
        }

        when (loadStates.append) {
            is LoadState.Error -&gt; {
                // The additional load failed. Call the retry() method
                // in order to retry the load operation.
                // ...
            }
            is LoadState.Loading -&gt; {
                // The adapter has started to load an additional page
                // ...
            }
            is LoadState.NotLoading -&gt; {
                if (loadStates.append.endOfPaginationReached) {
                    // The adapter has finished loading all of the data set
                    // ...
                }
                if (loadStates.refresh is LoadState.NotLoading) {
                    // The previous load (either initial or additional) completed
                    // ...
                }
            }
        }
  }
}"><pre><span class="pl-c"><span class="pl-c">//</span> Activities can use lifecycleScope directly, but Fragments should instead use</span>
<span class="pl-c"><span class="pl-c">//</span> viewLifecycleOwner.lifecycleScope.</span>
lifecycleScope.launch {
    pagingAdapter.loadStateFlow.collectLatest { loadStates <span class="pl-k">-&gt;</span>
        <span class="pl-k">when</span> (loadStates.refresh) {
            <span class="pl-k">is</span> <span class="pl-en">LoadState</span>.<span class="pl-en">Error</span> <span class="pl-k">-&gt;</span> {
                <span class="pl-c"><span class="pl-c">//</span> The initial load failed. Call the retry() method</span>
                <span class="pl-c"><span class="pl-c">//</span> in order to retry the load operation.</span>
                <span class="pl-c"><span class="pl-c">//</span> ...</span>
            }
            <span class="pl-k">is</span> <span class="pl-en">LoadState</span>.<span class="pl-en">Loading</span> <span class="pl-k">-&gt;</span> {
                <span class="pl-c"><span class="pl-c">//</span> The initial Load has begun</span>
                <span class="pl-c"><span class="pl-c">//</span> ...</span>
            }
        }

        <span class="pl-k">when</span> (loadStates.append) {
            <span class="pl-k">is</span> <span class="pl-en">LoadState</span>.<span class="pl-en">Error</span> <span class="pl-k">-&gt;</span> {
                <span class="pl-c"><span class="pl-c">//</span> The additional load failed. Call the retry() method</span>
                <span class="pl-c"><span class="pl-c">//</span> in order to retry the load operation.</span>
                <span class="pl-c"><span class="pl-c">//</span> ...</span>
            }
            <span class="pl-k">is</span> <span class="pl-en">LoadState</span>.<span class="pl-en">Loading</span> <span class="pl-k">-&gt;</span> {
                <span class="pl-c"><span class="pl-c">//</span> The adapter has started to load an additional page</span>
                <span class="pl-c"><span class="pl-c">//</span> ...</span>
            }
            <span class="pl-k">is</span> <span class="pl-en">LoadState</span>.<span class="pl-en">NotLoading</span> <span class="pl-k">-&gt;</span> {
                <span class="pl-k">if</span> (loadStates.append.endOfPaginationReached) {
                    <span class="pl-c"><span class="pl-c">//</span> The adapter has finished loading all of the data set</span>
                    <span class="pl-c"><span class="pl-c">//</span> ...</span>
                }
                <span class="pl-k">if</span> (loadStates.refresh <span class="pl-k">is</span> <span class="pl-en">LoadState</span>.<span class="pl-en">NotLoading</span>) {
                    <span class="pl-c"><span class="pl-c">//</span> The previous load (either initial or additional) completed</span>
                    <span class="pl-c"><span class="pl-c">//</span> ...</span>
                }
            }
        }
  }
}</pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Using FirebaseUI to populate a <code>ListView</code></h2><a id="user-content-using-firebaseui-to-populate-a-listview" class="anchor" aria-label="Permalink: Using FirebaseUI to populate a ListView" href="#using-firebaseui-to-populate-a-listview"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">ListView is the older, yet simpler way to handle lists of items. Using it is analogous to
using a <code>FirebaseRecyclerAdapter</code>, but with <code>FirebaseListAdapter</code> instead and no <code>ViewHolder</code>:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="FirebaseListOptions&lt;Chat&gt; options = new FirebaseListOptions.Builder&lt;Chat&gt;()
        .setQuery(query, Chat.class)
        .build();

FirebaseListAdapter&lt;Chat&gt; adapter = new FirebaseListAdapter&lt;Chat&gt;(options) {
    @Override
    protected void populateView(View v, Chat model, int position) {
        // Bind the Chat to the view
        // ...
    }
};"><pre><span class="pl-smi">FirebaseListOptions</span>&lt;<span class="pl-smi">Chat</span>&gt; <span class="pl-s1">options</span> = <span class="pl-k">new</span> <span class="pl-smi">FirebaseListOptions</span>.<span class="pl-smi">Builder</span>&lt;<span class="pl-smi">Chat</span>&gt;()
        .<span class="pl-en">setQuery</span>(<span class="pl-s1">query</span>, <span class="pl-smi">Chat</span>.<span class="pl-k">class</span>)
        .<span class="pl-en">build</span>();

<span class="pl-smi">FirebaseListAdapter</span>&lt;<span class="pl-smi">Chat</span>&gt; <span class="pl-s1">adapter</span> = <span class="pl-k">new</span> <span class="pl-smi">FirebaseListAdapter</span>&lt;<span class="pl-smi">Chat</span>&gt;(<span class="pl-s1">options</span>) {
    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">protected</span> <span class="pl-smi">void</span> <span class="pl-en">populateView</span>(<span class="pl-smi">View</span> <span class="pl-s1">v</span>, <span class="pl-smi">Chat</span> <span class="pl-s1">model</span>, <span class="pl-smi">int</span> <span class="pl-s1">position</span>) {
        <span class="pl-c">// Bind the Chat to the view</span>
        <span class="pl-c">// ...</span>
    }
};</pre></div>
<div class="markdown-heading" dir="auto"><h2 tabindex="-1" class="heading-element" dir="auto">Using FirebaseUI with indexed data</h2><a id="user-content-using-firebaseui-with-indexed-data" class="anchor" aria-label="Permalink: Using FirebaseUI with indexed data" href="#using-firebaseui-with-indexed-data"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">If your data is <a href="https://firebase.google.com/docs/database/android/structure-data#best_practices_for_data_structure" rel="nofollow">properly indexed</a>, change your adapter initialization
to use <code>setIndexedQuery()</code>:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="// keyQuery - the Firebase location containing the list of keys to be found in dataRef
// dataRef - the Firebase location to watch for data changes. Each key found at
//           keyRef's location represents a list item.
FirebaseRecyclerOptions&lt;Chat&gt; options = new FirebaseRecyclerOptions.Builder&lt;Chat&gt;()
        .setIndexedQuery(keyQuery, dataRef, Chat.class)
        .build();"><pre><span class="pl-c">// keyQuery - the Firebase location containing the list of keys to be found in dataRef</span>
<span class="pl-c">// dataRef - the Firebase location to watch for data changes. Each key found at</span>
<span class="pl-c">//           keyRef's location represents a list item.</span>
<span class="pl-smi">FirebaseRecyclerOptions</span>&lt;<span class="pl-smi">Chat</span>&gt; <span class="pl-s1">options</span> = <span class="pl-k">new</span> <span class="pl-smi">FirebaseRecyclerOptions</span>.<span class="pl-smi">Builder</span>&lt;<span class="pl-smi">Chat</span>&gt;()
        .<span class="pl-en">setIndexedQuery</span>(<span class="pl-s1">keyQuery</span>, <span class="pl-s1">dataRef</span>, <span class="pl-smi">Chat</span>.<span class="pl-k">class</span>)
        .<span class="pl-en">build</span>();</pre></div>
<p dir="auto">Where <code>keyQuery</code> is the location of your keys, and <code>dataRef</code> is the location of your data.</p>
<div class="markdown-heading" dir="auto"><h3 tabindex="-1" class="heading-element" dir="auto">A note on ordering</h3><a id="user-content-a-note-on-ordering" class="anchor" aria-label="Permalink: A note on ordering" href="#a-note-on-ordering"><svg data-component="Octicon" class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">The order in which you receive your data depends on the order from <code>keyRef</code>, not <code>dataRef</code>:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{
  &quot;data&quot;: {
    // This order doesn't matter, the order is taken from keys/(user1 or user2).
    &quot;3&quot;: true,
    &quot;1&quot;: &quot;some data&quot;,
    &quot;2&quot;: 5
  },
  &quot;keys&quot;: {
    // These two users have different orders for their data thanks to key side ordering.
    &quot;user1&quot;: {
      &quot;1&quot;: true,
      &quot;2&quot;: true,
      &quot;3&quot;: true
    },
    &quot;user2&quot;: {
      &quot;3&quot;: true,
      &quot;2&quot;: true,
      &quot;1&quot;: true
    }
  }
}"><pre><span class="pl-kos">{</span>
  <span class="pl-s">"data"</span>: <span class="pl-kos">{</span>
    <span class="pl-c">// This order doesn't matter, the order is taken from keys/(user1 or user2).</span>
    <span class="pl-s">"3"</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
    <span class="pl-s">"1"</span>: <span class="pl-s">"some data"</span><span class="pl-kos">,</span>
    <span class="pl-s">"2"</span>: <span class="pl-c1">5</span>
  <span class="pl-kos">}</span><span class="pl-kos">,</span>
  <span class="pl-s">"keys"</span>: <span class="pl-kos">{</span>
    <span class="pl-c">// These two users have different orders for their data thanks to key side ordering.</span>
    <span class="pl-s">"user1"</span>: <span class="pl-kos">{</span>
      <span class="pl-s">"1"</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
      <span class="pl-s">"2"</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
      <span class="pl-s">"3"</span>: <span class="pl-c1">true</span>
    <span class="pl-kos">}</span><span class="pl-kos">,</span>
    <span class="pl-s">"user2"</span>: <span class="pl-kos">{</span>
      <span class="pl-s">"3"</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
      <span class="pl-s">"2"</span>: <span class="pl-c1">true</span><span class="pl-kos">,</span>
      <span class="pl-s">"1"</span>: <span class="pl-c1">true</span>
    <span class="pl-kos">}</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
</article></div><div class="d-none"></div></section></div></div></div> </div> <!-- --> </div></div></div></div></div></div><div class="ScrollMarksContainer-module__scrollMarksContainer__Eu7uU" id="find-result-marks-container"></div><div class="d-none"></div><div class="d-none"></div></div> <!-- --> <!-- --> </div>
</react-app>




  </div>

</turbo-frame>

    </main>
  </div>

  </div>

          <footer class="footer f6 color-fg-muted color-border-subtle tmp-pt-7 tmp-pb-6 p-responsive" role="contentinfo"  >
  <h2 class='sr-only'>Footer</h2>

  


  <div class="d-flex flex-justify-center flex-items-center flex-column-reverse flex-lg-row flex-wrap flex-lg-nowrap">
    <div class="d-flex flex-items-center flex-shrink-0 mx-2">
      <a aria-label="GitHub Homepage" class="footer-octicon mr-2" href="https://github.com">
        <svg aria-hidden="true" data-component="Octicon" height="24" viewBox="0 0 24 24" version="1.1" width="24" data-view-component="true" class="octicon octicon-mark-github">
    <path d="M10.226 17.284c-2.965-.36-5.054-2.493-5.054-5.256 0-1.123.404-2.336 1.078-3.144-.292-.741-.247-2.314.09-2.965.898-.112 2.111.36 2.83 1.01.853-.269 1.752-.404 2.853-.404 1.1 0 1.999.135 2.807.382.696-.629 1.932-1.1 2.83-.988.315.606.36 2.179.067 2.942.72.854 1.101 2 1.101 3.167 0 2.763-2.089 4.852-5.098 5.234.763.494 1.28 1.572 1.28 2.807v2.336c0 .674.561 1.056 1.235.786 4.066-1.55 7.255-5.615 7.255-10.646C23.5 6.188 18.334 1 11.978 1 5.62 1 .5 6.188.5 12.545c0 4.986 3.167 9.12 7.435 10.669.606.225 1.19-.18 1.19-.786V20.63a2.9 2.9 0 0 1-1.078.224c-1.483 0-2.359-.808-2.987-2.313-.247-.607-.517-.966-1.034-1.033-.27-.023-.359-.135-.359-.27 0-.27.45-.471.898-.471.652 0 1.213.404 1.797 1.235.45.651.921.943 1.483.943.561 0 .92-.202 1.437-.719.382-.381.674-.718.944-.943"></path>
</svg>
</a>
      <span>
        &copy; 2026 GitHub,&nbsp;Inc.
      </span>
    </div>

    <nav aria-label="Footer">
      <h3 class="sr-only" id="sr-footer-heading">Footer navigation</h3>

      <ul class="list-style-none d-flex flex-justify-center flex-wrap mb-2 mb-lg-0" aria-labelledby="sr-footer-heading">


          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to Terms&quot;,&quot;label&quot;:&quot;text:terms&quot;}" href="https://docs.github.com/site-policy/github-terms/github-terms-of-service" data-view-component="true" class="Link--secondary Link">Terms</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to privacy&quot;,&quot;label&quot;:&quot;text:privacy&quot;}" href="https://docs.github.com/site-policy/privacy-policies/github-privacy-statement" data-view-component="true" class="Link--secondary Link">Privacy</a>
          </li>


            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to security&quot;,&quot;label&quot;:&quot;text:security&quot;}" href="https://github.com/security" data-view-component="true" class="Link--secondary Link">Security</a>
            </li>

            <li class="mx-2">
              <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to status&quot;,&quot;label&quot;:&quot;text:status&quot;}" href="https://www.githubstatus.com/" data-view-component="true" class="Link--secondary Link">Status</a>
            </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to community&quot;,&quot;label&quot;:&quot;text:community&quot;}" href="https://github.community/" data-view-component="true" class="Link--secondary Link">Community</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to docs&quot;,&quot;label&quot;:&quot;text:docs&quot;}" href="https://docs.github.com/" data-view-component="true" class="Link--secondary Link">Docs</a>
          </li>

          <li class="mx-2">
            <a data-analytics-event="{&quot;category&quot;:&quot;Footer&quot;,&quot;action&quot;:&quot;go to contact&quot;,&quot;label&quot;:&quot;text:contact&quot;}" href="https://support.github.com?tags=dotcom-footer" data-view-component="true" class="Link--secondary Link">Contact</a>
          </li>

          
<li class="mx-2" >
  <cookie-consent-link>
    <button
      type="button"
      class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent"
      data-action="click:cookie-consent-link#showConsentManagement"
      data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;cookies&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;cookies_link_subfooter_footer&quot;}"
    >
      Manage cookies
    </button>
  </cookie-consent-link>
</li>

  <li class="mx-2">
    <cookie-consent-link>
      <button
        type="button"
        class="Link--secondary underline-on-hover border-0 p-0 color-bg-transparent text-left"
        data-action="click:cookie-consent-link#showConsentManagement"
        data-analytics-event="{&quot;location&quot;:&quot;footer&quot;,&quot;action&quot;:&quot;dont_share_info&quot;,&quot;context&quot;:&quot;subfooter&quot;,&quot;tag&quot;:&quot;link&quot;,&quot;label&quot;:&quot;dont_share_info_link_subfooter_footer&quot;}"
      >
        Do not share my personal information
      </button>
    </cookie-consent-link>
  </li>

      </ul>
    </nav>
  </div>
</footer>



    <ghcc-consent id="ghcc" class="position-fixed bottom-0 left-0" style="z-index: 999999"
      data-locale="en"
      data-initial-cookie-consent-allowed=""
      data-cookie-consent-required="true"
    ></ghcc-consent>




  <div id="ajax-error-message" class="ajax-error-message flash flash-error" hidden>
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <button type="button" class="flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
    </button>
    You can’t perform that action at this time.
  </div>

    <template id="site-details-dialog">
  <details class="details-reset details-overlay details-overlay-dark lh-default color-fg-default hx_rsm" open>
    <summary role="button" aria-label="Close dialog"></summary>
    <details-dialog class="Box Box--overlay d-flex flex-column anim-fade-in fast hx_rsm-dialog hx_rsm-modal">
      <button class="Box-btn-octicon m-0 btn-octicon position-absolute right-0 top-0" type="button" aria-label="Close dialog" data-close-dialog>
        <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-x">
    <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z"></path>
</svg>
      </button>
      <div class="octocat-spinner tmp-my-6 js-details-dialog-spinner"></div>
    </details-dialog>
  </details>
</template>

    <div class="Popover js-hovercard-content position-absolute" style="display: none; outline: none;">
  <div class="Popover-message Popover-message--bottom-left Popover-message--large Box color-shadow-large" style="width:360px;">
  </div>
</div>

    <template id="snippet-clipboard-copy-button">
  <div class="zeroclipboard-container position-absolute right-0 top-0">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn js-clipboard-copy m-2 p-0" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2 tmp-m-2">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2 tmp-m-2">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>
<template id="snippet-clipboard-copy-button-unpositioned">
  <div class="zeroclipboard-container">
    <clipboard-copy aria-label="Copy code to clipboard" class="ClipboardButton btn btn-invisible js-clipboard-copy m-2 p-0 d-flex flex-justify-center flex-items-center" data-copy-feedback="Copied!" data-tooltip-direction="w">
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon">
    <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path>
</svg>
      <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none">
    <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"></path>
</svg>
    </clipboard-copy>
  </div>
</template>




    </div>
    <div id="js-global-screen-reader-notice" class="sr-only mt-n1" aria-live="polite" aria-atomic="true" ></div>
    <div id="js-global-screen-reader-notice-assertive" class="sr-only mt-n1" aria-live="assertive" aria-atomic="true"></div>
  </body>
</html>

