@app.route("/")defroot():# Verify Firebase auth.id_token=request.cookies.get("token")error_message=Noneclaims=Nonetimes=Noneifid_token:try:# Verify the token against the Firebase Auth API. This example# verifies the token on each page load. For improved performance,# some applications may wish to cache results in an encrypted# session store (see for instance# http://flask.pocoo.org/docs/1.0/quickstart/#sessions).claims=google.oauth2.id_token.verify_firebase_token(id_token,firebase_request_adapter)store_time(claims["email"],datetime.datetime.now(tz=datetime.timezone.utc))times=fetch_times(claims["email"],10)exceptValueErrorasexc:# This will be raised if the token is expired or any other# verification checks fail.error_message=str(exc)returnrender_template("index.html",user_data=claims,error_message=error_message,times=times)
# Copyright 2021 Google LLC## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.indexes:-kind:visitancestor:yesproperties:-name:timestampdirection:desc
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["わかりにくい","hardToUnderstand","thumb-down"],["情報またはサンプルコードが不正確","incorrectInformationOrSampleCode","thumb-down"],["必要な情報 / サンプルがない","missingTheInformationSamplesINeed","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-09-04 UTC。"],[[["\u003cp\u003eThe \u003ccode\u003eREGION_ID\u003c/code\u003e is a Google-assigned code based on the region selected during app creation, which is included in App Engine URLs for apps created after February 2020, and is optional for apps created before that date.\u003c/p\u003e\n"],["\u003cp\u003eThis guide instructs you on updating a web service to display only the last ten requests made by the currently authenticated user, using Firebase authentication and Firestore in Datastore mode.\u003c/p\u003e\n"],["\u003cp\u003eDatastore ancestors are used to link data to specific users, enabling the storage and retrieval of user-specific information in a hierarchical manner by identifying each user by their email.\u003c/p\u003e\n"],["\u003cp\u003eYou must manually create an \u003ccode\u003eindex.yaml\u003c/code\u003e file to define indexes for complex entities, such as \u003ccode\u003evisit\u003c/code\u003e entities with ancestors, which is necessary for Datastore to perform queries.\u003c/p\u003e\n"],["\u003cp\u003eAfter setting up the indexes and testing locally, you can redeploy the updated web service to App Engine using the \u003ccode\u003egcloud app deploy\u003c/code\u003e command.\u003c/p\u003e\n"]]],[],null,["# Personalize data for authenticated users\n\n### Region ID\n\nThe \u003cvar translate=\"no\"\u003eREGION_ID\u003c/var\u003e is an abbreviated code that Google assigns\nbased on the region you select when you create your app. The code does not\ncorrespond to a country or province, even though some region IDs may appear\nsimilar to commonly used country and province codes. For apps created after\nFebruary 2020, \u003cvar translate=\"no\"\u003eREGION_ID\u003c/var\u003e`.r` is included in\nApp Engine URLs. For existing apps created before this date, the\nregion ID is optional in the URL.\n\nLearn more\n[about region IDs](/appengine/docs/standard/python3/how-requests-are-routed#region-id). \nOK\n\n\u003cbr /\u003e\n\n| **Note:** If you are deploying a new Python web service to Google Cloud, we recommend getting started with [Cloud Run](/run/docs/quickstarts/build-and-deploy/deploy-python-service).\n\nUse authenticated user information to store and retrieve user-specific data\nand personalize each user's experience with your web service.\n\nIn a previous step, you updated the web service to display the last ten requests\nfrom all users. In this step, you use authenticated user information to update your\nweb service so that the page displays only a list of the last ten requests made by\nthe currently authenticated user.\n\nBefore you Begin\n----------------\n\nIf you have completed all the previous steps in this guide, skip this section.\nOtherwise, complete one of the following:\n\n- Start from [Build a Python 3 App](/appengine/docs/standard/python3/building-app)\n and complete all the steps leading up to this one.\n\n- If you already have a\n [Google Cloud project](/appengine/docs/standard/python3/building-app/creating-gcp-project),\n you can continue by downloading a copy of the web service and adding Firebase:\n\n 1. Download the sample application repository using\n [Git](https://git-scm.com/):\n\n git clone https://github.com/GoogleCloudPlatform/python-docs-samples\n\n Alternatively, you can [download the sample](https://github.com/GoogleCloudPlatform/python-docs-samples/archive/master.zip) as a zip\n file and then extract it.\n 2. Navigate to the directory that contains a copy of the files from the\n previous step:\n\n cd python-docs-samples/appengine/standard_python3/building-an-app/building-an-app-3\n\n 3. [Add Firebase to your Google Cloud project and web service](/appengine/docs/standard/python3/building-app/adding-firebase#adding-firebase-to-your-project).\n\nStore and retrieve user-specific data\n-------------------------------------\n\nYou can indicate that data is connected to a certain user by using\nFirestore in Datastore mode (Datastore) ancestors, which allow you to organize your\nDatastore data hierarchically.\n\nTo do this, complete the following steps:\n\n1. Update your `store_time` and `fetch_time`\n methods to use Datastore ancestors for storing and retrieving\n `visit` entities:\n\n datastore_client = datastore.Client()\n\n def store_time(email, dt):\n entity = datastore.Entity(key=datastore_client.key(\"User\", email, \"visit\"))\n entity.update({\"timestamp\": dt})\n\n datastore_client.put(entity)\n\n\n def fetch_times(email, limit):\n ancestor = datastore_client.key(\"User\", email)\n query = datastore_client.query(kind=\"visit\", ancestor=ancestor)\n query.order = [\"-timestamp\"]\n\n times = query.fetch(limit=limit)\n\n return times\n\n Each `visit` entity now has an ancestor that it is connected to. These ancestors\n are Datastore entities that represent individual authenticated users.\n Each ancestor's *key* includes the `User` *kind* and a custom ID, which is\n the authenticated user's email address.\n You use the ancestor key to query the database for only the\n times that are associated with a specific user.\n2. Update the `store_times` method call in your `root` method and move it\n inside the `id_token` conditional so that it only runs if the server has\n authenticated a user:\n\n @app.route(\"/\")\n def root():\n # Verify Firebase auth.\n id_token = request.cookies.get(\"token\")\n error_message = None\n claims = None\n times = None\n\n if id_token:\n try:\n # Verify the token against the Firebase Auth API. This example\n # verifies the token on each page load. For improved performance,\n # some applications may wish to cache results in an encrypted\n # session store (see for instance\n # http://flask.pocoo.org/docs/1.0/quickstart/#sessions).\n claims = google.oauth2.id_token.verify_firebase_token(\n id_token, firebase_request_adapter\n )\n\n store_time(claims[\"email\"], datetime.datetime.now(tz=datetime.timezone.utc))\n times = fetch_times(claims[\"email\"], 10)\n\n except ValueError as exc:\n # This will be raised if the token is expired or any other\n # verification checks fail.\n error_message = str(exc)\n\n return render_template(\n \"index.html\", user_data=claims, error_message=error_message, times=times\n )\n\nConfigure indexes\n-----------------\n\nDatastore makes queries based on indexes. For simple entities,\nDatastore automatically generates these indexes. However, it cannot\nautomatically generate indexes for more complicated entities, including those\nwith ancestors.\nBecause of this, you need to manually create an index for `visit` entities\nso that Datastore can perform queries involving `visit` entities.\n\nTo create an index for `visit` entities, complete the following steps:\n\n1. Create an `index.yaml` file in the root directory of your project, for\n example `building-an-app`, and add the following index:\n\n # Copyright 2021 Google LLC\n #\n # Licensed under the Apache License, Version 2.0 (the \"License\");\n # you may not use this file except in compliance with the License.\n # You may obtain a copy of the License at\n #\n # http://www.apache.org/licenses/LICENSE-2.0\n #\n # Unless required by applicable law or agreed to in writing, software\n # distributed under the License is distributed on an \"AS IS\" BASIS,\n # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n # See the License for the specific language governing permissions and\n # limitations under the License.\n\n indexes:\n\n - kind: visit\n ancestor: yes\n properties:\n - name: timestamp\n direction: desc\n\n2. Deploy your `index.yaml` indexes in Datastore by running\n the following command and following the prompts:\n\n gcloud datastore indexes create index.yaml\n\nIt can take a while for Datastore to create indexes. Creating\nindexes before deploying your web service to App Engine both allows\nyou to test locally using those indexes and prevents exceptions that might\noccur for queries that require an index that is still in the process of being\nbuilt.\n| **Tip:** You can view the index you created in the Datastore console:\n\n[View your indexes](https://console.cloud.google.com/datastore/indexes)\n\nFor more information on making Datastore indexes, see\n[Configuring Datastore Indexes](/appengine/docs/standard/python/config/indexconfig).\n\nTesting your web service\n------------------------\n\nTest your web service by running it locally in a virtual environment:\n\n1. Run the following command in your\n project's main directory to run your web service.\n If you have not set up a virtual environment for local testing, see\n [testing your web service](/appengine/docs/standard/python3/building-app/writing-web-service#testing_your_web_service).\n\n python main.py\n\n2. Enter the following address in your web browser to view your web service:\n\n http://localhost:8080\n\nDeploy your web service\n-----------------------\n\nNow that you have Datastore working locally, you can re-deploy your web\nservice to App Engine.\n\nRun the following command from the root directory of your project,\nwhere your `app.yaml` file is located: \n\n gcloud app deploy\n\nAll traffic is automatically routed to the new version you deployed.\n\nFor more information on managing versions,\nsee [Manage Services and Versions](/appengine/docs/standard/python3/building-app/deploying-web-service#managing_services_and_versions).\n\nView your service\n-----------------\n\nTo quickly launch your browser and access your web service at\n\n`https://`\u003cvar translate=\"no\"\u003ePROJECT_ID\u003c/var\u003e`.`\u003cvar translate=\"no\"\u003e\u003ca href=\"#appengine-urls\" style=\"border-bottom: 1px dotted #999\" class=\"devsite-dialog-button\" data-modal-dialog-id=\"regional_url\" track-type=\"progressiveHelp\" track-name=\"modalHelp\" track-metadata-goal=\"regionalURL\"\u003eREGION_ID\u003c/a\u003e\u003c/var\u003e`.r.appspot.com`, run the following command: \n\n gcloud app browse\n\nNext Steps\n----------\n\nCongratulations! You've successfully built a web service that uses\nDatastore data storage and Firebase authentication to provide\nauthenticated users with a personalized web page.\n\nNow you can clean up by shutting down, deactivating, or disabling billing for\nyour project."]]