├── .coveragerc ├── .flake8 ├── .github ├── .OwlBot.lock.yaml ├── .OwlBot.yaml ├── CODEOWNERS ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── support_request.md ├── PULL_REQUEST_TEMPLATE.md ├── auto-approve.yml ├── auto-label.yaml ├── blunderbuss.yml ├── flakybot.yaml ├── header-checker-lint.yml ├── release-please.yml ├── release-trigger.yml ├── snippet-bot.yml ├── sync-repo-settings.yaml └── workflows │ ├── docs.yml │ ├── lint.yml │ ├── mypy.yml │ ├── system_emulated.yml │ └── unittest.yml ├── .gitignore ├── .kokoro ├── build.sh ├── continuous │ ├── common.cfg │ ├── continuous.cfg │ └── prerelease-deps.cfg ├── populate-secrets.sh ├── presubmit │ ├── common.cfg │ ├── prerelease-deps.cfg │ ├── presubmit.cfg │ └── system-3.7.cfg ├── samples │ ├── lint │ │ ├── common.cfg │ │ ├── continuous.cfg │ │ ├── periodic.cfg │ │ └── presubmit.cfg │ ├── python3.10 │ │ ├── common.cfg │ │ ├── continuous.cfg │ │ ├── periodic-head.cfg │ │ ├── periodic.cfg │ │ └── presubmit.cfg │ ├── python3.11 │ │ ├── common.cfg │ │ ├── continuous.cfg │ │ ├── periodic-head.cfg │ │ ├── periodic.cfg │ │ └── presubmit.cfg │ ├── python3.12 │ │ ├── common.cfg │ │ ├── continuous.cfg │ │ ├── periodic-head.cfg │ │ ├── periodic.cfg │ │ └── presubmit.cfg │ ├── python3.13 │ │ ├── common.cfg │ │ ├── continuous.cfg │ │ ├── periodic-head.cfg │ │ ├── periodic.cfg │ │ └── presubmit.cfg │ ├── python3.7 │ │ ├── common.cfg │ │ ├── continuous.cfg │ │ ├── periodic-head.cfg │ │ ├── periodic.cfg │ │ └── presubmit.cfg │ ├── python3.8 │ │ ├── common.cfg │ │ ├── continuous.cfg │ │ ├── periodic-head.cfg │ │ ├── periodic.cfg │ │ └── presubmit.cfg │ └── python3.9 │ │ ├── common.cfg │ │ ├── continuous.cfg │ │ ├── periodic-head.cfg │ │ ├── periodic.cfg │ │ └── presubmit.cfg ├── test-samples-against-head.sh ├── test-samples-impl.sh ├── test-samples.sh ├── trampoline.sh └── trampoline_v2.sh ├── .pre-commit-config.yaml ├── .release-please-manifest.json ├── .repo-metadata.json ├── .trampolinerc ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.rst ├── LICENSE ├── MANIFEST.in ├── Makefile_v1 ├── README.rst ├── SECURITY.md ├── UPGRADING.md ├── docs ├── README.rst ├── UPGRADING.md ├── _static │ └── custom.css ├── _templates │ └── layout.html ├── changelog.md ├── conf.py ├── firestore_admin_v1 │ └── admin_client.rst ├── firestore_bundle │ └── bundles.rst ├── firestore_v1 │ ├── aggregation.rst │ ├── batch.rst │ ├── bulk_writer.rst │ ├── client.rst │ ├── collection.rst │ ├── document.rst │ ├── field_path.rst │ ├── query.rst │ ├── transaction.rst │ ├── transforms.rst │ └── types.rst ├── index.rst ├── multiprocessing.rst └── summary_overview.md ├── google └── cloud │ ├── firestore │ ├── __init__.py │ └── gapic_version.py │ ├── firestore_admin_v1 │ ├── __init__.py │ ├── gapic_metadata.json │ ├── gapic_version.py │ ├── py.typed │ ├── services │ │ ├── __init__.py │ │ └── firestore_admin │ │ │ ├── __init__.py │ │ │ ├── async_client.py │ │ │ ├── client.py │ │ │ ├── pagers.py │ │ │ └── transports │ │ │ ├── README.rst │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── grpc.py │ │ │ ├── grpc_asyncio.py │ │ │ ├── rest.py │ │ │ └── rest_base.py │ └── types │ │ ├── __init__.py │ │ ├── backup.py │ │ ├── database.py │ │ ├── field.py │ │ ├── firestore_admin.py │ │ ├── index.py │ │ ├── location.py │ │ ├── operation.py │ │ ├── schedule.py │ │ └── user_creds.py │ ├── firestore_bundle │ ├── __init__.py │ ├── _helpers.py │ ├── bundle.py │ ├── gapic_metadata.json │ ├── gapic_version.py │ ├── py.typed │ ├── services │ │ └── __init__.py │ └── types │ │ ├── __init__.py │ │ └── bundle.py │ └── firestore_v1 │ ├── __init__.py │ ├── _helpers.py │ ├── aggregation.py │ ├── async_aggregation.py │ ├── async_batch.py │ ├── async_client.py │ ├── async_collection.py │ ├── async_document.py │ ├── async_query.py │ ├── async_stream_generator.py │ ├── async_transaction.py │ ├── async_vector_query.py │ ├── base_aggregation.py │ ├── base_batch.py │ ├── base_client.py │ ├── base_collection.py │ ├── base_document.py │ ├── base_query.py │ ├── base_transaction.py │ ├── base_vector_query.py │ ├── batch.py │ ├── bulk_batch.py │ ├── bulk_writer.py │ ├── client.py │ ├── collection.py │ ├── document.py │ ├── field_path.py │ ├── gapic_metadata.json │ ├── gapic_version.py │ ├── order.py │ ├── py.typed │ ├── query.py │ ├── query_profile.py │ ├── query_results.py │ ├── rate_limiter.py │ ├── services │ ├── __init__.py │ └── firestore │ │ ├── __init__.py │ │ ├── async_client.py │ │ ├── client.py │ │ ├── pagers.py │ │ └── transports │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── base.py │ │ ├── grpc.py │ │ ├── grpc_asyncio.py │ │ ├── rest.py │ │ └── rest_base.py │ ├── stream_generator.py │ ├── transaction.py │ ├── transforms.py │ ├── types │ ├── __init__.py │ ├── aggregation_result.py │ ├── bloom_filter.py │ ├── common.py │ ├── document.py │ ├── firestore.py │ ├── query.py │ ├── query_profile.py │ └── write.py │ ├── vector.py │ ├── vector_query.py │ └── watch.py ├── mypy.ini ├── noxfile.py ├── owlbot.py ├── pylint.config.py ├── pytest.ini ├── release-please-config.json ├── renovate.json ├── samples ├── AUTHORING_GUIDE.md └── CONTRIBUTING.md ├── scripts ├── decrypt-secrets.sh ├── fixup_firestore_admin_v1_keywords.py ├── fixup_firestore_v1_keywords.py └── readme-gen │ ├── readme_gen.py │ └── templates │ ├── README.tmpl.rst │ ├── auth.tmpl.rst │ ├── auth_api_key.tmpl.rst │ ├── install_deps.tmpl.rst │ └── install_portaudio.tmpl.rst ├── setup.cfg ├── setup.py ├── testing ├── .gitignore ├── constraints-3.10.txt ├── constraints-3.11.txt ├── constraints-3.12.txt ├── constraints-3.13.txt ├── constraints-3.7.txt ├── constraints-3.8.txt └── constraints-3.9.txt └── tests ├── __init__.py ├── credentials.json.enc ├── system ├── test__helpers.py ├── test_system.py ├── test_system_async.py └── util │ ├── bootstrap_vector_index.py │ └── cleanup_firestore_documents.py └── unit ├── __init__.py ├── gapic ├── __init__.py ├── bundle │ └── __init__.py ├── firestore_admin_v1 │ ├── __init__.py │ └── test_firestore_admin.py ├── firestore_v1 │ ├── __init__.py │ └── test_firestore.py └── v1 │ └── __init__.py ├── test_firestore_shim.py ├── test_packaging.py └── v1 ├── __init__.py ├── _test_helpers.py ├── conformance_tests.py ├── test__helpers.py ├── test_aggregation.py ├── test_async_aggregation.py ├── test_async_batch.py ├── test_async_client.py ├── test_async_collection.py ├── test_async_document.py ├── test_async_query.py ├── test_async_stream_generator.py ├── test_async_transaction.py ├── test_async_vector_query.py ├── test_base_batch.py ├── test_base_client.py ├── test_base_collection.py ├── test_base_document.py ├── test_base_query.py ├── test_base_transaction.py ├── test_batch.py ├── test_bulk_batch.py ├── test_bulk_writer.py ├── test_bundle.py ├── test_client.py ├── test_collection.py ├── test_cross_language.py ├── test_document.py ├── test_field_path.py ├── test_order.py ├── test_query.py ├── test_query_profile.py ├── test_query_results.py ├── test_rate_limiter.py ├── test_stream_generator.py ├── test_transaction.py ├── test_transforms.py ├── test_vector.py ├── test_vector_query.py ├── test_watch.py └── testdata ├── create-all-transforms.json ├── create-arrayremove-multi.json ├── create-arrayremove-nested.json ├── create-arrayremove-noarray-nested.json ├── create-arrayremove-noarray.json ├── create-arrayremove-with-st.json ├── create-arrayremove.json ├── create-arrayunion-multi.json ├── create-arrayunion-nested.json ├── create-arrayunion-noarray-nested.json ├── create-arrayunion-noarray.json ├── create-arrayunion-with-st.json ├── create-arrayunion.json ├── create-basic.json ├── create-complex.json ├── create-del-noarray-nested.json ├── create-del-noarray.json ├── create-empty.json ├── create-nodel.json ├── create-nosplit.json ├── create-special-chars.json ├── create-st-alone.json ├── create-st-multi.json ├── create-st-nested.json ├── create-st-noarray-nested.json ├── create-st-noarray.json ├── create-st-with-empty-map.json ├── create-st.json ├── delete-exists-precond.json ├── delete-no-precond.json ├── delete-time-precond.json ├── get-basic.json ├── listen-add-mod-del-add.json ├── listen-add-one.json ├── listen-add-three.json ├── listen-doc-remove.json ├── listen-empty.json ├── listen-filter-nop.json ├── listen-multi-docs.json ├── listen-nocurrent.json ├── listen-nomod.json ├── listen-removed-target-ids.json ├── listen-reset.json ├── listen-target-add-nop.json ├── listen-target-add-wrong-id.json ├── listen-target-remove.json ├── query-arrayremove-cursor.json ├── query-arrayremove-where.json ├── query-arrayunion-cursor.json ├── query-arrayunion-where.json ├── query-bad-NaN.json ├── query-bad-null.json ├── query-cursor-docsnap-order.json ├── query-cursor-docsnap-orderby-name.json ├── query-cursor-docsnap-where-eq.json ├── query-cursor-docsnap-where-neq-orderby.json ├── query-cursor-docsnap-where-neq.json ├── query-cursor-docsnap.json ├── query-cursor-endbefore-empty-map.json ├── query-cursor-endbefore-empty.json ├── query-cursor-no-order.json ├── query-cursor-startat-empty-map.json ├── query-cursor-startat-empty.json ├── query-cursor-vals-1a.json ├── query-cursor-vals-1b.json ├── query-cursor-vals-2.json ├── query-cursor-vals-docid.json ├── query-cursor-vals-last-wins.json ├── query-del-cursor.json ├── query-del-where.json ├── query-invalid-operator.json ├── query-invalid-path-order.json ├── query-invalid-path-select.json ├── query-invalid-path-where.json ├── query-offset-limit-last-wins.json ├── query-offset-limit.json ├── query-order.json ├── query-select-empty.json ├── query-select-last-wins.json ├── query-select.json ├── query-st-cursor.json ├── query-st-where.json ├── query-where-2.json ├── query-where-NaN.json ├── query-where-null.json ├── query-where.json ├── query-wrong-collection.json ├── set-all-transforms.json ├── set-arrayremove-multi.json ├── set-arrayremove-nested.json ├── set-arrayremove-noarray-nested.json ├── set-arrayremove-noarray.json ├── set-arrayremove-with-st.json ├── set-arrayremove.json ├── set-arrayunion-merge.json ├── set-arrayunion-multi.json ├── set-arrayunion-nested.json ├── set-arrayunion-noarray-nested.json ├── set-arrayunion-noarray.json ├── set-arrayunion-with-st.json ├── set-arrayunion.json ├── set-basic.json ├── set-complex.json ├── set-del-merge-alone.json ├── set-del-merge.json ├── set-del-mergeall.json ├── set-del-noarray-nested.json ├── set-del-noarray.json ├── set-del-nomerge.json ├── set-del-nonleaf.json ├── set-del-wo-merge.json ├── set-empty.json ├── set-merge-fp.json ├── set-merge-nested.json ├── set-merge-nonleaf.json ├── set-merge-prefix.json ├── set-merge-present.json ├── set-merge.json ├── set-mergeall-empty.json ├── set-mergeall-nested.json ├── set-mergeall.json ├── set-nodel.json ├── set-nosplit.json ├── set-special-chars.json ├── set-st-alone-mergeall.json ├── set-st-alone.json ├── set-st-merge-both.json ├── set-st-merge-nonleaf-alone.json ├── set-st-merge-nonleaf.json ├── set-st-merge-nowrite.json ├── set-st-mergeall.json ├── set-st-multi.json ├── set-st-nested.json ├── set-st-noarray-nested.json ├── set-st-noarray.json ├── set-st-nomerge.json ├── set-st-with-empty-map.json ├── set-st.json ├── update-all-transforms.json ├── update-arrayremove-alone.json ├── update-arrayremove-multi.json ├── update-arrayremove-nested.json ├── update-arrayremove-noarray-nested.json ├── update-arrayremove-noarray.json ├── update-arrayremove-with-st.json ├── update-arrayremove.json ├── update-arrayunion-alone.json ├── update-arrayunion-multi.json ├── update-arrayunion-nested.json ├── update-arrayunion-noarray-nested.json ├── update-arrayunion-noarray.json ├── update-arrayunion-with-st.json ├── update-arrayunion.json ├── update-badchar.json ├── update-basic.json ├── update-complex.json ├── update-del-alone.json ├── update-del-dot.json ├── update-del-nested.json ├── update-del-noarray-nested.json ├── update-del-noarray.json ├── update-del.json ├── update-exists-precond.json ├── update-fp-empty-component.json ├── update-nested-transform-and-nested-value.json ├── update-no-paths.json ├── update-paths-all-transforms.json ├── update-paths-arrayremove-alone.json ├── update-paths-arrayremove-multi.json ├── update-paths-arrayremove-nested.json ├── update-paths-arrayremove-noarray-nested.json ├── update-paths-arrayremove-noarray.json ├── update-paths-arrayremove-with-st.json ├── update-paths-arrayremove.json ├── update-paths-arrayunion-alone.json ├── update-paths-arrayunion-multi.json ├── update-paths-arrayunion-nested.json ├── update-paths-arrayunion-noarray-nested.json ├── update-paths-arrayunion-noarray.json ├── update-paths-arrayunion-with-st.json ├── update-paths-arrayunion.json ├── update-paths-basic.json ├── update-paths-complex.json ├── update-paths-del-alone.json ├── update-paths-del-nested.json ├── update-paths-del-noarray-nested.json ├── update-paths-del-noarray.json ├── update-paths-del.json ├── update-paths-exists-precond.json ├── update-paths-fp-del.json ├── update-paths-fp-dup-transforms.json ├── update-paths-fp-dup.json ├── update-paths-fp-empty-component.json ├── update-paths-fp-empty.json ├── update-paths-fp-multi.json ├── update-paths-fp-nosplit.json ├── update-paths-nested-transform-and-nested-value.json ├── update-paths-no-paths.json ├── update-paths-prefix-1.json ├── update-paths-prefix-2.json ├── update-paths-prefix-3.json ├── update-paths-special-chars.json ├── update-paths-st-alone.json ├── update-paths-st-multi.json ├── update-paths-st-nested.json ├── update-paths-st-noarray-nested.json ├── update-paths-st-noarray.json ├── update-paths-st-with-empty-map.json ├── update-paths-st.json ├── update-paths-uptime.json ├── update-prefix-1.json ├── update-prefix-2.json ├── update-prefix-3.json ├── update-quoting.json ├── update-split-top-level.json ├── update-split.json ├── update-st-alone.json ├── update-st-dot.json ├── update-st-multi.json ├── update-st-nested.json ├── update-st-noarray-nested.json ├── update-st-noarray.json ├── update-st-with-empty-map.json ├── update-st.json └── update-uptime.json /.coveragerc: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2024 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Generated by synthtool. DO NOT EDIT! 18 | [run] 19 | branch = True 20 | omit = 21 | google/__init__.py 22 | google/cloud/__init__.py 23 | 24 | [report] 25 | fail_under = 100 26 | show_missing = True 27 | exclude_lines = 28 | # Re-enable the standard pragma 29 | pragma: NO COVER 30 | # Ignore debug-only repr 31 | def __repr__ 32 | # Ignore abstract methods 33 | raise NotImplementedError 34 | omit = 35 | */gapic/*.py 36 | */proto/*.py 37 | */core/*.py 38 | */site-packages/*.py 39 | google/cloud/__init__.py 40 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2024 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Generated by synthtool. DO NOT EDIT! 18 | [flake8] 19 | ignore = E203, E231, E266, E501, W503 20 | exclude = 21 | # Exclude generated code. 22 | **/proto/** 23 | **/gapic/** 24 | **/services/** 25 | **/types/** 26 | *_pb2.py 27 | 28 | # Standard linting exemptions. 29 | **/.nox/** 30 | __pycache__, 31 | .git, 32 | *.pyc, 33 | conf.py 34 | -------------------------------------------------------------------------------- /.github/.OwlBot.lock.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2025 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | docker: 15 | image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest 16 | digest: sha256:25de45b58e52021d3a24a6273964371a97a4efeefe6ad3845a64e697c63b6447 17 | # created: 2025-04-14T14:34:43.260858345Z 18 | -------------------------------------------------------------------------------- /.github/.OwlBot.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | docker: 16 | image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest 17 | 18 | deep-remove-regex: 19 | - /owl-bot-staging 20 | 21 | deep-preserve-regex: 22 | - /owl-bot-staging/firestore/v1beta1 23 | 24 | deep-copy-regex: 25 | - source: /google/firestore/(v.*)/.*-py/(.*) 26 | dest: /owl-bot-staging/firestore/$1/$2 27 | - source: /google/firestore/admin/(v.*)/.*-py/(.*) 28 | dest: /owl-bot-staging/firestore_admin/$1/$2 29 | - source: /google/firestore/bundle/(.*-py)/(.*) 30 | dest: /owl-bot-staging/firestore_bundle/$1/$2 31 | 32 | begin-after-commit-hash: 107ed1217b5e87048263f52cd3911d5f851aca7e 33 | 34 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code owners file. 2 | # This file controls who is tagged for review for any given pull request. 3 | # 4 | # For syntax help see: 5 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax 6 | # Note: This file is autogenerated. To make changes to the codeowner team, please update .repo-metadata.json. 7 | 8 | # @googleapis/yoshi-python @googleapis/api-firestore @googleapis/api-firestore-partners are the default owners for changes in this repo 9 | * @googleapis/yoshi-python @googleapis/api-firestore @googleapis/api-firestore-partners 10 | 11 | # @googleapis/python-samples-reviewers @googleapis/api-firestore @googleapis/api-firestore-partners are the default owners for samples changes 12 | /samples/ @googleapis/python-samples-reviewers @googleapis/api-firestore @googleapis/api-firestore-partners 13 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows [Google's Open Source Community 28 | Guidelines](https://opensource.google.com/conduct/). 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | Thanks for stopping by to let us know something could be better! 8 | 9 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 10 | 11 | Please run down the following list and make sure you've tried the usual "quick fixes": 12 | 13 | - Search the issues already opened: https://github.com/googleapis/python-firestore/issues 14 | - Search StackOverflow: https://stackoverflow.com/questions/tagged/google-cloud-platform+python 15 | 16 | If you are still having issues, please be sure to include as much information as possible: 17 | 18 | #### Environment details 19 | 20 | - OS type and version: 21 | - Python version: `python --version` 22 | - pip version: `pip --version` 23 | - `google-cloud-firestore` version: `pip show google-cloud-firestore` 24 | 25 | #### Steps to reproduce 26 | 27 | 1. ? 28 | 2. ? 29 | 30 | #### Code example 31 | 32 | ```python 33 | # example 34 | ``` 35 | 36 | #### Stack trace 37 | ``` 38 | # example 39 | ``` 40 | 41 | Making sure to follow these steps will guarantee the quickest resolution possible. 42 | 43 | Thanks! 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this library 4 | 5 | --- 6 | 7 | Thanks for stopping by to let us know something could be better! 8 | 9 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 10 | 11 | **Is your feature request related to a problem? Please describe.** 12 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | **Additional context** 18 | Add any other context or screenshots about the feature request here. 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/support_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Support request 3 | about: If you have a support contract with Google, please create an issue in the Google Cloud Support console. 4 | 5 | --- 6 | 7 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 8 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: 2 | - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/python-firestore/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea 3 | - [ ] Ensure the tests and linter pass 4 | - [ ] Code coverage does not decrease (if any source code was changed) 5 | - [ ] Appropriate docs were updated (if necessary) 6 | 7 | Fixes # 🦕 8 | -------------------------------------------------------------------------------- /.github/auto-approve.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/googleapis/repo-automation-bots/tree/main/packages/auto-approve 2 | processes: 3 | - "OwlBotTemplateChanges" 4 | -------------------------------------------------------------------------------- /.github/auto-label.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | requestsize: 15 | enabled: true 16 | 17 | path: 18 | pullrequest: true 19 | paths: 20 | samples: "samples" 21 | -------------------------------------------------------------------------------- /.github/blunderbuss.yml: -------------------------------------------------------------------------------- 1 | # Blunderbuss config 2 | # 3 | # This file controls who is assigned for pull requests and issues. 4 | # Note: This file is autogenerated. To make changes to the assignee 5 | # team, please update `codeowner_team` in `.repo-metadata.json`. 6 | assign_issues: 7 | - googleapis/api-firestore 8 | - googleapis/api-firestore-partners 9 | 10 | assign_issues_by: 11 | - labels: 12 | - "samples" 13 | to: 14 | - googleapis/python-samples-reviewers 15 | - googleapis/api-firestore 16 | - googleapis/api-firestore-partners 17 | 18 | assign_prs: 19 | - googleapis/api-firestore 20 | - googleapis/api-firestore-partners 21 | -------------------------------------------------------------------------------- /.github/flakybot.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | issuePriority: p2 -------------------------------------------------------------------------------- /.github/header-checker-lint.yml: -------------------------------------------------------------------------------- 1 | {"allowedCopyrightHolders": ["Google LLC"], 2 | "allowedLicenses": ["Apache-2.0", "MIT", "BSD-3"], 3 | "ignoreFiles": ["**/requirements.txt", "**/requirements-test.txt", "**/__init__.py", "samples/**/constraints.txt", "samples/**/constraints-test.txt"], 4 | "sourceFileExtensions": [ 5 | "ts", 6 | "js", 7 | "java", 8 | "sh", 9 | "Dockerfile", 10 | "yaml", 11 | "py", 12 | "html", 13 | "txt" 14 | ] 15 | } -------------------------------------------------------------------------------- /.github/release-please.yml: -------------------------------------------------------------------------------- 1 | releaseType: python 2 | handleGHRelease: true 3 | manifest: true 4 | # NOTE: this section is generated by synthtool.languages.python 5 | # See https://github.com/googleapis/synthtool/blob/master/synthtool/languages/python.py 6 | branches: 7 | - branch: v1 8 | handleGHRelease: true 9 | releaseType: python 10 | - branch: v0 11 | handleGHRelease: true 12 | releaseType: python 13 | -------------------------------------------------------------------------------- /.github/release-trigger.yml: -------------------------------------------------------------------------------- 1 | enabled: true 2 | multiScmName: python-firestore 3 | -------------------------------------------------------------------------------- /.github/snippet-bot.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/python-firestore/d8e3af1f9dbdfaf5df0d993a0a7e28883472c621/.github/snippet-bot.yml -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | branches: 4 | - main 5 | name: docs 6 | jobs: 7 | docs: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v4 12 | - name: Setup Python 13 | uses: actions/setup-python@v5 14 | with: 15 | python-version: "3.10" 16 | - name: Install nox 17 | run: | 18 | python -m pip install --upgrade setuptools pip wheel 19 | python -m pip install nox 20 | - name: Run docs 21 | run: | 22 | nox -s docs 23 | docfx: 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@v4 28 | - name: Setup Python 29 | uses: actions/setup-python@v5 30 | with: 31 | python-version: "3.10" 32 | - name: Install nox 33 | run: | 34 | python -m pip install --upgrade setuptools pip wheel 35 | python -m pip install nox 36 | - name: Run docfx 37 | run: | 38 | nox -s docfx 39 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | branches: 4 | - main 5 | name: lint 6 | jobs: 7 | lint: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v4 12 | - name: Setup Python 13 | uses: actions/setup-python@v5 14 | with: 15 | python-version: "3.8" 16 | - name: Install nox 17 | run: | 18 | python -m pip install --upgrade setuptools pip wheel 19 | python -m pip install nox 20 | - name: Run lint 21 | run: | 22 | nox -s lint 23 | - name: Run lint_setup_py 24 | run: | 25 | nox -s lint_setup_py 26 | -------------------------------------------------------------------------------- /.github/workflows/mypy.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | branches: 4 | - main 5 | name: mypy 6 | jobs: 7 | lint: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v4 12 | - name: Setup Python 13 | uses: actions/setup-python@v5 14 | with: 15 | python-version: "3.8" 16 | - name: Install nox 17 | run: | 18 | python -m pip install --upgrade setuptools pip wheel 19 | python -m pip install nox 20 | - name: Run mypy 21 | run: | 22 | nox -s mypy 23 | -------------------------------------------------------------------------------- /.github/workflows/system_emulated.yml: -------------------------------------------------------------------------------- 1 | name: "Run systests on emulator" 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | 7 | jobs: 8 | 9 | run-systests: 10 | runs-on: ubuntu-22.04 11 | 12 | steps: 13 | 14 | - name: Checkout 15 | uses: actions/checkout@v4 16 | 17 | - name: Setup Python 18 | uses: actions/setup-python@v5 19 | with: 20 | python-version: '3.7' 21 | 22 | # firestore emulator requires java 21+ 23 | - name: Setup Java 24 | uses: actions/setup-java@v4 25 | with: 26 | distribution: temurin 27 | java-version: '21' 28 | 29 | - name: Setup GCloud SDK 30 | uses: google-github-actions/setup-gcloud@v2.1.1 31 | 32 | - name: Install / run Nox 33 | run: | 34 | python -m pip install --upgrade setuptools pip 35 | python -m pip install nox 36 | nox -s system_emulated 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | *.sw[op] 3 | 4 | # C extensions 5 | *.so 6 | 7 | # Packages 8 | *.egg 9 | *.egg-info 10 | dist 11 | build 12 | eggs 13 | .eggs 14 | parts 15 | bin 16 | var 17 | sdist 18 | develop-eggs 19 | .installed.cfg 20 | lib 21 | lib64 22 | __pycache__ 23 | 24 | # Installer logs 25 | pip-log.txt 26 | 27 | # Unit test / coverage reports 28 | .coverage 29 | .nox 30 | .cache 31 | .pytest_cache 32 | .pytype 33 | 34 | 35 | # Mac 36 | .DS_Store 37 | 38 | # JetBrains 39 | .idea 40 | 41 | # VS Code 42 | .vscode 43 | 44 | # emacs 45 | *~ 46 | 47 | # Built documentation 48 | docs/_build 49 | bigquery/docs/generated 50 | docs.metadata 51 | 52 | # Virtual environment 53 | env/ 54 | venv/ 55 | 56 | # Test logs 57 | coverage.xml 58 | *sponge_log.xml 59 | 60 | # System test environment variables. 61 | system_tests/local_test_setup 62 | 63 | # Make sure a generated file isn't accidentally committed. 64 | pylintrc 65 | pylintrc.test 66 | .make/** 67 | -------------------------------------------------------------------------------- /.kokoro/continuous/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Download resources for system tests (service account key, etc.) 14 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-python" 15 | 16 | # Use the trampoline script to run in docker. 17 | build_file: "python-firestore/.kokoro/trampoline.sh" 18 | 19 | # Configure the docker image for kokoro-trampoline. 20 | env_vars: { 21 | key: "TRAMPOLINE_IMAGE" 22 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi" 23 | } 24 | env_vars: { 25 | key: "TRAMPOLINE_BUILD_FILE" 26 | value: "github/python-firestore/.kokoro/build.sh" 27 | } 28 | -------------------------------------------------------------------------------- /.kokoro/continuous/continuous.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto -------------------------------------------------------------------------------- /.kokoro/continuous/prerelease-deps.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Only run this nox session. 4 | env_vars: { 5 | key: "NOX_SESSION" 6 | value: "prerelease_deps" 7 | } 8 | -------------------------------------------------------------------------------- /.kokoro/presubmit/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Download resources for system tests (service account key, etc.) 14 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-python" 15 | 16 | # Use the trampoline script to run in docker. 17 | build_file: "python-firestore/.kokoro/trampoline.sh" 18 | 19 | # Configure the docker image for kokoro-trampoline. 20 | env_vars: { 21 | key: "TRAMPOLINE_IMAGE" 22 | value: "gcr.io/cloud-devrel-kokoro-resources/python-multi" 23 | } 24 | env_vars: { 25 | key: "TRAMPOLINE_BUILD_FILE" 26 | value: "github/python-firestore/.kokoro/build.sh" 27 | } 28 | -------------------------------------------------------------------------------- /.kokoro/presubmit/prerelease-deps.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Only run this nox session. 4 | env_vars: { 5 | key: "NOX_SESSION" 6 | value: "prerelease_deps" 7 | } 8 | -------------------------------------------------------------------------------- /.kokoro/presubmit/presubmit.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Disable system tests. 4 | env_vars: { 5 | key: "RUN_SYSTEM_TESTS" 6 | value: "false" 7 | } 8 | -------------------------------------------------------------------------------- /.kokoro/presubmit/system-3.7.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Only run this nox session. 4 | env_vars: { 5 | key: "NOX_SESSION" 6 | value: "system-3.7" 7 | } -------------------------------------------------------------------------------- /.kokoro/samples/lint/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Specify which tests to run 11 | env_vars: { 12 | key: "RUN_TESTS_SESSION" 13 | value: "lint" 14 | } 15 | 16 | env_vars: { 17 | key: "TRAMPOLINE_BUILD_FILE" 18 | value: "github/python-firestore/.kokoro/test-samples.sh" 19 | } 20 | 21 | # Configure the docker image for kokoro-trampoline. 22 | env_vars: { 23 | key: "TRAMPOLINE_IMAGE" 24 | value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" 25 | } 26 | 27 | # Download secrets for samples 28 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" 29 | 30 | # Download trampoline resources. 31 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 32 | 33 | # Use the trampoline script to run in docker. 34 | build_file: "python-firestore/.kokoro/trampoline_v2.sh" -------------------------------------------------------------------------------- /.kokoro/samples/lint/continuous.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/lint/periodic.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "False" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/lint/presubmit.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.10/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Specify which tests to run 11 | env_vars: { 12 | key: "RUN_TESTS_SESSION" 13 | value: "py-3.10" 14 | } 15 | 16 | # Declare build specific Cloud project. 17 | env_vars: { 18 | key: "BUILD_SPECIFIC_GCLOUD_PROJECT" 19 | value: "python-docs-samples-tests-310" 20 | } 21 | 22 | env_vars: { 23 | key: "TRAMPOLINE_BUILD_FILE" 24 | value: "github/python-firestore/.kokoro/test-samples.sh" 25 | } 26 | 27 | # Configure the docker image for kokoro-trampoline. 28 | env_vars: { 29 | key: "TRAMPOLINE_IMAGE" 30 | value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" 31 | } 32 | 33 | # Download secrets for samples 34 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" 35 | 36 | # Download trampoline resources. 37 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 38 | 39 | # Use the trampoline script to run in docker. 40 | build_file: "python-firestore/.kokoro/trampoline_v2.sh" -------------------------------------------------------------------------------- /.kokoro/samples/python3.10/continuous.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.10/periodic-head.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } 7 | 8 | env_vars: { 9 | key: "TRAMPOLINE_BUILD_FILE" 10 | value: "github/python-firestore/.kokoro/test-samples-against-head.sh" 11 | } 12 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.10/periodic.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "False" 6 | } 7 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.10/presubmit.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.11/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Specify which tests to run 11 | env_vars: { 12 | key: "RUN_TESTS_SESSION" 13 | value: "py-3.11" 14 | } 15 | 16 | # Declare build specific Cloud project. 17 | env_vars: { 18 | key: "BUILD_SPECIFIC_GCLOUD_PROJECT" 19 | value: "python-docs-samples-tests-311" 20 | } 21 | 22 | env_vars: { 23 | key: "TRAMPOLINE_BUILD_FILE" 24 | value: "github/python-firestore/.kokoro/test-samples.sh" 25 | } 26 | 27 | # Configure the docker image for kokoro-trampoline. 28 | env_vars: { 29 | key: "TRAMPOLINE_IMAGE" 30 | value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" 31 | } 32 | 33 | # Download secrets for samples 34 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" 35 | 36 | # Download trampoline resources. 37 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 38 | 39 | # Use the trampoline script to run in docker. 40 | build_file: "python-firestore/.kokoro/trampoline_v2.sh" -------------------------------------------------------------------------------- /.kokoro/samples/python3.11/continuous.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.11/periodic-head.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } 7 | 8 | env_vars: { 9 | key: "TRAMPOLINE_BUILD_FILE" 10 | value: "github/python-firestore/.kokoro/test-samples-against-head.sh" 11 | } 12 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.11/periodic.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "False" 6 | } 7 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.11/presubmit.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.12/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Specify which tests to run 11 | env_vars: { 12 | key: "RUN_TESTS_SESSION" 13 | value: "py-3.12" 14 | } 15 | 16 | # Declare build specific Cloud project. 17 | env_vars: { 18 | key: "BUILD_SPECIFIC_GCLOUD_PROJECT" 19 | value: "python-docs-samples-tests-312" 20 | } 21 | 22 | env_vars: { 23 | key: "TRAMPOLINE_BUILD_FILE" 24 | value: "github/python-firestore/.kokoro/test-samples.sh" 25 | } 26 | 27 | # Configure the docker image for kokoro-trampoline. 28 | env_vars: { 29 | key: "TRAMPOLINE_IMAGE" 30 | value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" 31 | } 32 | 33 | # Download secrets for samples 34 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" 35 | 36 | # Download trampoline resources. 37 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 38 | 39 | # Use the trampoline script to run in docker. 40 | build_file: "python-firestore/.kokoro/trampoline_v2.sh" -------------------------------------------------------------------------------- /.kokoro/samples/python3.12/continuous.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.12/periodic-head.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } 7 | 8 | env_vars: { 9 | key: "TRAMPOLINE_BUILD_FILE" 10 | value: "github/python-firestore/.kokoro/test-samples-against-head.sh" 11 | } 12 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.12/periodic.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "False" 6 | } 7 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.12/presubmit.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.13/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Specify which tests to run 11 | env_vars: { 12 | key: "RUN_TESTS_SESSION" 13 | value: "py-3.13" 14 | } 15 | 16 | # Declare build specific Cloud project. 17 | env_vars: { 18 | key: "BUILD_SPECIFIC_GCLOUD_PROJECT" 19 | value: "python-docs-samples-tests-313" 20 | } 21 | 22 | env_vars: { 23 | key: "TRAMPOLINE_BUILD_FILE" 24 | value: "github/python-firestore/.kokoro/test-samples.sh" 25 | } 26 | 27 | # Configure the docker image for kokoro-trampoline. 28 | env_vars: { 29 | key: "TRAMPOLINE_IMAGE" 30 | value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" 31 | } 32 | 33 | # Download secrets for samples 34 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" 35 | 36 | # Download trampoline resources. 37 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 38 | 39 | # Use the trampoline script to run in docker. 40 | build_file: "python-firestore/.kokoro/trampoline_v2.sh" 41 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.13/continuous.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.13/periodic-head.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } 7 | 8 | env_vars: { 9 | key: "TRAMPOLINE_BUILD_FILE" 10 | value: "github/python-firestore/.kokoro/test-samples-against-head.sh" 11 | } 12 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.13/periodic.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "False" 6 | } 7 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.13/presubmit.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.7/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Specify which tests to run 11 | env_vars: { 12 | key: "RUN_TESTS_SESSION" 13 | value: "py-3.7" 14 | } 15 | 16 | # Declare build specific Cloud project. 17 | env_vars: { 18 | key: "BUILD_SPECIFIC_GCLOUD_PROJECT" 19 | value: "python-docs-samples-tests-py37" 20 | } 21 | 22 | env_vars: { 23 | key: "TRAMPOLINE_BUILD_FILE" 24 | value: "github/python-firestore/.kokoro/test-samples.sh" 25 | } 26 | 27 | # Configure the docker image for kokoro-trampoline. 28 | env_vars: { 29 | key: "TRAMPOLINE_IMAGE" 30 | value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" 31 | } 32 | 33 | # Download secrets for samples 34 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" 35 | 36 | # Download trampoline resources. 37 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 38 | 39 | # Use the trampoline script to run in docker. 40 | build_file: "python-firestore/.kokoro/trampoline_v2.sh" -------------------------------------------------------------------------------- /.kokoro/samples/python3.7/continuous.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.7/periodic-head.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } 7 | 8 | env_vars: { 9 | key: "TRAMPOLINE_BUILD_FILE" 10 | value: "github/python-firestore/.kokoro/test-samples-against-head.sh" 11 | } 12 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.7/periodic.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "False" 6 | } 7 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.7/presubmit.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.8/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Specify which tests to run 11 | env_vars: { 12 | key: "RUN_TESTS_SESSION" 13 | value: "py-3.8" 14 | } 15 | 16 | # Declare build specific Cloud project. 17 | env_vars: { 18 | key: "BUILD_SPECIFIC_GCLOUD_PROJECT" 19 | value: "python-docs-samples-tests-py38" 20 | } 21 | 22 | env_vars: { 23 | key: "TRAMPOLINE_BUILD_FILE" 24 | value: "github/python-firestore/.kokoro/test-samples.sh" 25 | } 26 | 27 | # Configure the docker image for kokoro-trampoline. 28 | env_vars: { 29 | key: "TRAMPOLINE_IMAGE" 30 | value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" 31 | } 32 | 33 | # Download secrets for samples 34 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" 35 | 36 | # Download trampoline resources. 37 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 38 | 39 | # Use the trampoline script to run in docker. 40 | build_file: "python-firestore/.kokoro/trampoline_v2.sh" -------------------------------------------------------------------------------- /.kokoro/samples/python3.8/continuous.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.8/periodic-head.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } 7 | 8 | env_vars: { 9 | key: "TRAMPOLINE_BUILD_FILE" 10 | value: "github/python-firestore/.kokoro/test-samples-against-head.sh" 11 | } 12 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.8/periodic.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "False" 6 | } 7 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.8/presubmit.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.9/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Specify which tests to run 11 | env_vars: { 12 | key: "RUN_TESTS_SESSION" 13 | value: "py-3.9" 14 | } 15 | 16 | # Declare build specific Cloud project. 17 | env_vars: { 18 | key: "BUILD_SPECIFIC_GCLOUD_PROJECT" 19 | value: "python-docs-samples-tests-py39" 20 | } 21 | 22 | env_vars: { 23 | key: "TRAMPOLINE_BUILD_FILE" 24 | value: "github/python-firestore/.kokoro/test-samples.sh" 25 | } 26 | 27 | # Configure the docker image for kokoro-trampoline. 28 | env_vars: { 29 | key: "TRAMPOLINE_IMAGE" 30 | value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" 31 | } 32 | 33 | # Download secrets for samples 34 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" 35 | 36 | # Download trampoline resources. 37 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 38 | 39 | # Use the trampoline script to run in docker. 40 | build_file: "python-firestore/.kokoro/trampoline_v2.sh" -------------------------------------------------------------------------------- /.kokoro/samples/python3.9/continuous.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/samples/python3.9/periodic-head.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } 7 | 8 | env_vars: { 9 | key: "TRAMPOLINE_BUILD_FILE" 10 | value: "github/python-firestore/.kokoro/test-samples-against-head.sh" 11 | } 12 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.9/periodic.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "False" 6 | } 7 | -------------------------------------------------------------------------------- /.kokoro/samples/python3.9/presubmit.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | env_vars: { 4 | key: "INSTALL_LIBRARY_FROM_SOURCE" 5 | value: "True" 6 | } -------------------------------------------------------------------------------- /.kokoro/test-samples-against-head.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2024 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # https://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # A customized test runner for samples. 17 | # 18 | # For periodic builds, you can specify this file for testing against head. 19 | 20 | # `-e` enables the script to automatically fail when a command fails 21 | # `-o pipefail` sets the exit code to the rightmost comment to exit with a non-zero 22 | set -eo pipefail 23 | # Enables `**` to include files nested inside sub-folders 24 | shopt -s globstar 25 | 26 | exec .kokoro/test-samples-impl.sh 27 | -------------------------------------------------------------------------------- /.kokoro/trampoline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2024 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -eo pipefail 17 | 18 | # Always run the cleanup script, regardless of the success of bouncing into 19 | # the container. 20 | function cleanup() { 21 | chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh 22 | ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh 23 | echo "cleanup"; 24 | } 25 | trap cleanup EXIT 26 | 27 | $(dirname $0)/populate-secrets.sh # Secret Manager secrets. 28 | python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # 15 | # See https://pre-commit.com for more information 16 | # See https://pre-commit.com/hooks.html for more hooks 17 | repos: 18 | - repo: https://github.com/pre-commit/pre-commit-hooks 19 | rev: v4.0.1 20 | hooks: 21 | - id: trailing-whitespace 22 | - id: end-of-file-fixer 23 | - id: check-yaml 24 | - repo: https://github.com/psf/black 25 | rev: 23.7.0 26 | hooks: 27 | - id: black 28 | - repo: https://github.com/pycqa/flake8 29 | rev: 6.1.0 30 | hooks: 31 | - id: flake8 32 | -------------------------------------------------------------------------------- /.release-please-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | ".": "2.21.0" 3 | } -------------------------------------------------------------------------------- /.repo-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "firestore", 3 | "name_pretty": "Cloud Firestore", 4 | "product_documentation": "https://cloud.google.com/firestore", 5 | "client_documentation": "https://cloud.google.com/python/docs/reference/firestore/latest", 6 | "issue_tracker": "https://issuetracker.google.com/savedsearches/5337669", 7 | "release_level": "stable", 8 | "language": "python", 9 | "library_type": "GAPIC_COMBO", 10 | "repo": "googleapis/python-firestore", 11 | "distribution_name": "google-cloud-firestore", 12 | "api_id": "firestore.googleapis.com", 13 | "requires_billing": true, 14 | "default_version": "v1", 15 | "codeowner_team": "@googleapis/api-firestore @googleapis/api-firestore-partners", 16 | "api_shortname": "firestore", 17 | "api_description": "is a fully-managed NoSQL document database for mobile, web, and server development from Firebase and Google Cloud Platform. It's backed by a multi-region replicated database that ensures once data is committed, it's durable even in the face of unexpected disasters. Not only that, but despite being a distributed database, it's also strongly consistent and offers seamless integration with other Firebase and Google Cloud Platform products, including Google Cloud Functions." 18 | } 19 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2024 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # Generated by synthtool. DO NOT EDIT! 18 | include README.rst LICENSE 19 | recursive-include google *.json *.proto py.typed 20 | recursive-include tests * 21 | global-exclude *.py[co] 22 | global-exclude __pycache__ 23 | 24 | # Exclude scripts for samples readmegen 25 | prune scripts/readme-gen 26 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). 4 | 5 | The Google Security Team will respond within 5 working days of your report on g.co/vulnz. 6 | 7 | We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. 8 | -------------------------------------------------------------------------------- /docs/README.rst: -------------------------------------------------------------------------------- 1 | ../README.rst -------------------------------------------------------------------------------- /docs/_static/custom.css: -------------------------------------------------------------------------------- 1 | div#python2-eol { 2 | border-color: red; 3 | border-width: medium; 4 | } 5 | 6 | /* Ensure minimum width for 'Parameters' / 'Returns' column */ 7 | dl.field-list > dt { 8 | min-width: 100px 9 | } 10 | 11 | /* Insert space between methods for readability */ 12 | dl.method { 13 | padding-top: 10px; 14 | padding-bottom: 10px 15 | } 16 | 17 | /* Insert empty space between classes */ 18 | dl.class { 19 | padding-bottom: 50px 20 | } 21 | -------------------------------------------------------------------------------- /docs/changelog.md: -------------------------------------------------------------------------------- 1 | ../CHANGELOG.md -------------------------------------------------------------------------------- /docs/firestore_admin_v1/admin_client.rst: -------------------------------------------------------------------------------- 1 | Firestore Admin Client 2 | ~~~~~~~~~~~~~~~~~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_admin_v1.services.firestore_admin.client 5 | :members: 6 | :show-inheritance: 7 | -------------------------------------------------------------------------------- /docs/firestore_bundle/bundles.rst: -------------------------------------------------------------------------------- 1 | Bundles 2 | ~~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_bundle.bundle 5 | :members: 6 | :show-inheritance: 7 | -------------------------------------------------------------------------------- /docs/firestore_v1/aggregation.rst: -------------------------------------------------------------------------------- 1 | Aggregation 2 | ~~~~~~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_v1.aggregation 5 | :members: 6 | :show-inheritance: 7 | 8 | .. automodule:: google.cloud.firestore_v1.base_aggregation 9 | :members: 10 | :show-inheritance: 11 | 12 | .. automodule:: google.cloud.firestore_v1.async_aggregation 13 | :members: 14 | :show-inheritance: 15 | -------------------------------------------------------------------------------- /docs/firestore_v1/batch.rst: -------------------------------------------------------------------------------- 1 | Batches 2 | ~~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_v1.base_batch 5 | :members: 6 | :show-inheritance: 7 | 8 | .. automodule:: google.cloud.firestore_v1.batch 9 | :members: 10 | :show-inheritance: 11 | 12 | .. automodule:: google.cloud.firestore_v1.async_batch 13 | :members: 14 | :show-inheritance: 15 | -------------------------------------------------------------------------------- /docs/firestore_v1/bulk_writer.rst: -------------------------------------------------------------------------------- 1 | Bulk Writer 2 | ~~~~~~~~~~~ 3 | 4 | .. autoclass:: google.cloud.firestore_v1.bulk_writer.BulkWriter 5 | :members: 6 | :show-inheritance: 7 | -------------------------------------------------------------------------------- /docs/firestore_v1/client.rst: -------------------------------------------------------------------------------- 1 | Client 2 | ~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_v1.base_client 5 | :members: 6 | :show-inheritance: 7 | 8 | .. automodule:: google.cloud.firestore_v1.client 9 | :members: 10 | :show-inheritance: 11 | 12 | .. automodule:: google.cloud.firestore_v1.async_client 13 | :members: 14 | :show-inheritance: 15 | -------------------------------------------------------------------------------- /docs/firestore_v1/collection.rst: -------------------------------------------------------------------------------- 1 | Collections 2 | ~~~~~~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_v1.base_collection 5 | :members: 6 | :show-inheritance: 7 | 8 | .. automodule:: google.cloud.firestore_v1.collection 9 | :members: 10 | :show-inheritance: 11 | 12 | .. automodule:: google.cloud.firestore_v1.async_collection 13 | :members: 14 | :show-inheritance: 15 | -------------------------------------------------------------------------------- /docs/firestore_v1/document.rst: -------------------------------------------------------------------------------- 1 | Documents 2 | ~~~~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_v1.base_document 5 | :members: 6 | :show-inheritance: 7 | 8 | .. automodule:: google.cloud.firestore_v1.document 9 | :members: 10 | :show-inheritance: 11 | 12 | .. automodule:: google.cloud.firestore_v1.async_document 13 | :members: 14 | :show-inheritance: 15 | -------------------------------------------------------------------------------- /docs/firestore_v1/field_path.rst: -------------------------------------------------------------------------------- 1 | Field Paths 2 | ~~~~~~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_v1.field_path 5 | :members: 6 | :show-inheritance: 7 | 8 | -------------------------------------------------------------------------------- /docs/firestore_v1/query.rst: -------------------------------------------------------------------------------- 1 | Queries 2 | ~~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_v1.base_query 5 | :members: 6 | :show-inheritance: 7 | 8 | .. automodule:: google.cloud.firestore_v1.query 9 | :members: 10 | :show-inheritance: 11 | 12 | .. automodule:: google.cloud.firestore_v1.async_query 13 | :members: 14 | :show-inheritance: 15 | -------------------------------------------------------------------------------- /docs/firestore_v1/transaction.rst: -------------------------------------------------------------------------------- 1 | Transactions 2 | ~~~~~~~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_v1.base_transaction 5 | :inherited-members: 6 | :members: 7 | :show-inheritance: 8 | 9 | .. automodule:: google.cloud.firestore_v1.transaction 10 | :inherited-members: 11 | :members: 12 | :show-inheritance: 13 | 14 | .. automodule:: google.cloud.firestore_v1.async_transaction 15 | :inherited-members: 16 | :members: 17 | :show-inheritance: 18 | -------------------------------------------------------------------------------- /docs/firestore_v1/transforms.rst: -------------------------------------------------------------------------------- 1 | Transforms 2 | ~~~~~~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_v1.transforms 5 | :members: 6 | :show-inheritance: 7 | -------------------------------------------------------------------------------- /docs/firestore_v1/types.rst: -------------------------------------------------------------------------------- 1 | Types 2 | ~~~~~ 3 | 4 | .. automodule:: google.cloud.firestore_v1.types 5 | :members: 6 | :show-inheritance: 7 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. include:: README.rst 2 | 3 | .. include:: multiprocessing.rst 4 | 5 | API Reference 6 | ------------- 7 | 8 | .. toctree:: 9 | :maxdepth: 2 10 | 11 | firestore_admin_v1/admin_client 12 | 13 | firestore_bundle/bundles 14 | 15 | firestore_v1/aggregation 16 | firestore_v1/batch 17 | firestore_v1/bulk_writer 18 | firestore_v1/client 19 | firestore_v1/collection 20 | firestore_v1/document 21 | firestore_v1/field_path 22 | firestore_v1/query 23 | firestore_v1/transaction 24 | firestore_v1/transforms 25 | firestore_v1/types 26 | 27 | Migration Guide 28 | --------------- 29 | 30 | See the guide below for instructions on migrating to the 2.x release of this library. 31 | 32 | .. toctree:: 33 | :maxdepth: 2 34 | 35 | UPGRADING 36 | 37 | Changelog 38 | --------- 39 | 40 | For a list of all ``google-cloud-firestore`` releases: 41 | 42 | .. toctree:: 43 | :maxdepth: 2 44 | 45 | changelog 46 | 47 | .. toctree:: 48 | :hidden: 49 | 50 | summary_overview.md 51 | -------------------------------------------------------------------------------- /docs/multiprocessing.rst: -------------------------------------------------------------------------------- 1 | .. note:: 2 | 3 | Because this client uses :mod:`grpc` library, it is safe to 4 | share instances across threads. In multiprocessing scenarios, the best 5 | practice is to create client instances *after* the invocation of 6 | :func:`os.fork` by :class:`multiprocessing.pool.Pool` or 7 | :class:`multiprocessing.Process`. 8 | -------------------------------------------------------------------------------- /docs/summary_overview.md: -------------------------------------------------------------------------------- 1 | [ 2 | This is a templated file. Adding content to this file may result in it being 3 | reverted. Instead, if you want to place additional content, create an 4 | "overview_content.md" file in `docs/` directory. The Sphinx tool will 5 | pick up on the content and merge the content. 6 | ]: # 7 | 8 | # Cloud Firestore API 9 | 10 | Overview of the APIs available for Cloud Firestore API. 11 | 12 | ## All entries 13 | 14 | Classes, methods and properties & attributes for 15 | Cloud Firestore API. 16 | 17 | [classes](https://cloud.google.com/python/docs/reference/firestore/latest/summary_class.html) 18 | 19 | [methods](https://cloud.google.com/python/docs/reference/firestore/latest/summary_method.html) 20 | 21 | [properties and 22 | attributes](https://cloud.google.com/python/docs/reference/firestore/latest/summary_property.html) 23 | -------------------------------------------------------------------------------- /google/cloud/firestore/gapic_version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2022 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | __version__ = "2.21.0" # {x-release-please-version} 17 | -------------------------------------------------------------------------------- /google/cloud/firestore_admin_v1/gapic_version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2022 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | __version__ = "2.21.0" # {x-release-please-version} 17 | -------------------------------------------------------------------------------- /google/cloud/firestore_admin_v1/py.typed: -------------------------------------------------------------------------------- 1 | # Marker file for PEP 561. 2 | # The google-cloud-firestore-admin package uses inline types. 3 | -------------------------------------------------------------------------------- /google/cloud/firestore_admin_v1/services/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | -------------------------------------------------------------------------------- /google/cloud/firestore_admin_v1/services/firestore_admin/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | from .client import FirestoreAdminClient 17 | from .async_client import FirestoreAdminAsyncClient 18 | 19 | __all__ = ( 20 | "FirestoreAdminClient", 21 | "FirestoreAdminAsyncClient", 22 | ) 23 | -------------------------------------------------------------------------------- /google/cloud/firestore_admin_v1/services/firestore_admin/transports/README.rst: -------------------------------------------------------------------------------- 1 | 2 | transport inheritance structure 3 | _______________________________ 4 | 5 | `FirestoreAdminTransport` is the ABC for all transports. 6 | - public child `FirestoreAdminGrpcTransport` for sync gRPC transport (defined in `grpc.py`). 7 | - public child `FirestoreAdminGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). 8 | - private child `_BaseFirestoreAdminRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). 9 | - public child `FirestoreAdminRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). 10 | -------------------------------------------------------------------------------- /google/cloud/firestore_admin_v1/types/location.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | from __future__ import annotations 17 | 18 | from typing import MutableMapping, MutableSequence 19 | 20 | import proto # type: ignore 21 | 22 | 23 | __protobuf__ = proto.module( 24 | package="google.firestore.admin.v1", 25 | manifest={ 26 | "LocationMetadata", 27 | }, 28 | ) 29 | 30 | 31 | class LocationMetadata(proto.Message): 32 | r"""The metadata message for 33 | [google.cloud.location.Location.metadata][google.cloud.location.Location.metadata]. 34 | 35 | """ 36 | 37 | 38 | __all__ = tuple(sorted(__protobuf__.manifest)) 39 | -------------------------------------------------------------------------------- /google/cloud/firestore_bundle/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | from google.cloud.firestore_bundle import gapic_version as package_version 17 | 18 | __version__ = package_version.__version__ 19 | 20 | 21 | from .types.bundle import BundledDocumentMetadata 22 | from .types.bundle import BundledQuery 23 | from .types.bundle import BundleElement 24 | from .types.bundle import BundleMetadata 25 | from .types.bundle import NamedQuery 26 | 27 | from .bundle import FirestoreBundle 28 | 29 | __all__ = ( 30 | "BundleElement", 31 | "BundleMetadata", 32 | "BundledDocumentMetadata", 33 | "BundledQuery", 34 | "FirestoreBundle", 35 | "NamedQuery", 36 | ) 37 | -------------------------------------------------------------------------------- /google/cloud/firestore_bundle/_helpers.py: -------------------------------------------------------------------------------- 1 | from google.cloud.firestore_v1.base_query import BaseQuery 2 | from google.cloud.firestore_bundle.types import BundledQuery 3 | 4 | 5 | def limit_type_of_query(query: BaseQuery) -> int: 6 | """BundledQuery.LimitType equivalent of this query.""" 7 | 8 | return ( 9 | BundledQuery.LimitType.LAST 10 | if query._limit_to_last 11 | else BundledQuery.LimitType.FIRST 12 | ) 13 | -------------------------------------------------------------------------------- /google/cloud/firestore_bundle/gapic_metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", 3 | "language": "python", 4 | "libraryPackage": "google.cloud.bundle", 5 | "protoPackage": "google.firestore.bundle", 6 | "schema": "1.0" 7 | } 8 | -------------------------------------------------------------------------------- /google/cloud/firestore_bundle/gapic_version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2022 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | __version__ = "2.21.0" # {x-release-please-version} 17 | -------------------------------------------------------------------------------- /google/cloud/firestore_bundle/py.typed: -------------------------------------------------------------------------------- 1 | # Marker file for PEP 561. 2 | # The google-cloud-bundle package uses inline types. 3 | -------------------------------------------------------------------------------- /google/cloud/firestore_bundle/services/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | -------------------------------------------------------------------------------- /google/cloud/firestore_bundle/types/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | from .bundle import ( 17 | BundledDocumentMetadata, 18 | BundledQuery, 19 | BundleElement, 20 | BundleMetadata, 21 | NamedQuery, 22 | ) 23 | 24 | __all__ = ( 25 | "BundledDocumentMetadata", 26 | "BundledQuery", 27 | "BundleElement", 28 | "BundleMetadata", 29 | "NamedQuery", 30 | ) 31 | -------------------------------------------------------------------------------- /google/cloud/firestore_v1/gapic_version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2022 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | __version__ = "2.21.0" # {x-release-please-version} 17 | -------------------------------------------------------------------------------- /google/cloud/firestore_v1/py.typed: -------------------------------------------------------------------------------- 1 | # Marker file for PEP 561. 2 | # The google-cloud-firestore package uses inline types. 3 | -------------------------------------------------------------------------------- /google/cloud/firestore_v1/services/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | -------------------------------------------------------------------------------- /google/cloud/firestore_v1/services/firestore/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | from .client import FirestoreClient 17 | from .async_client import FirestoreAsyncClient 18 | 19 | __all__ = ( 20 | "FirestoreClient", 21 | "FirestoreAsyncClient", 22 | ) 23 | -------------------------------------------------------------------------------- /google/cloud/firestore_v1/services/firestore/transports/README.rst: -------------------------------------------------------------------------------- 1 | 2 | transport inheritance structure 3 | _______________________________ 4 | 5 | `FirestoreTransport` is the ABC for all transports. 6 | - public child `FirestoreGrpcTransport` for sync gRPC transport (defined in `grpc.py`). 7 | - public child `FirestoreGrpcAsyncIOTransport` for async gRPC transport (defined in `grpc_asyncio.py`). 8 | - private child `_BaseFirestoreRestTransport` for base REST transport with inner classes `_BaseMETHOD` (defined in `rest_base.py`). 9 | - public child `FirestoreRestTransport` for sync REST transport with inner classes `METHOD` derived from the parent's corresponding `_BaseMETHOD` classes (defined in `rest.py`). 10 | -------------------------------------------------------------------------------- /mypy.ini: -------------------------------------------------------------------------------- 1 | [mypy] 2 | python_version = 3.6 3 | namespace_packages = True 4 | -------------------------------------------------------------------------------- /pylint.config.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """This module is used to configure gcp-devrel-py-tools run-pylint.""" 16 | 17 | # Library configuration 18 | 19 | # library_additions = {} 20 | # library_replacements = {} 21 | 22 | # Test configuration 23 | 24 | # test_additions = copy.deepcopy(library_additions) 25 | # test_replacements = copy.deepcopy(library_replacements) 26 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | filterwarnings = 3 | # treat all warnings as errors 4 | error 5 | # Remove once https://github.com/protocolbuffers/protobuf/issues/12186 is fixed 6 | ignore:.*custom tp_new.*in Python 3.14:DeprecationWarning 7 | # Remove once https://github.com/googleapis/python-api-common-protos/pull/187/files is merged 8 | ignore:.*pkg_resources.declare_namespace:DeprecationWarning 9 | ignore:.*pkg_resources is deprecated as an API:DeprecationWarning 10 | # Remove once https://github.com/googleapis/python-firestore/issues/804 is fixed 11 | ignore:.*Detected filter using positional arguments:UserWarning 12 | # Remove once https://github.com/googleapis/python-firestore/pull/716 is merged 13 | ignore:datetime.datetime.utcfromtimestamp\(\) is deprecated:DeprecationWarning 14 | ignore:datetime.datetime.utcnow\(\) is deprecated:DeprecationWarning 15 | # Remove warning once https://github.com/grpc/grpc/issues/35974 is fixed 16 | ignore:unclosed:ResourceWarning 17 | # Remove after support for Python 3.7 is dropped 18 | ignore:After January 1, 2024, new releases of this library will drop support for Python 3.7:DeprecationWarning 19 | # Remove warning once https://github.com/googleapis/gapic-generator-python/issues/1939 is fixed 20 | ignore:get_mtls_endpoint_and_cert_source is deprecated.:DeprecationWarning 21 | -------------------------------------------------------------------------------- /release-please-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": 3 | "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", 4 | "packages": { 5 | ".": { 6 | "release-type": "python", 7 | "extra-files": [ 8 | "google/cloud/firestore/gapic_version.py", 9 | "google/cloud/firestore_v1/gapic_version.py", 10 | "google/cloud/firestore_admin_v1/gapic_version.py", 11 | "google/cloud/firestore_bundle/gapic_version.py" 12 | ] 13 | } 14 | }, 15 | "release-type": "python", 16 | "plugins": [ 17 | { 18 | "type": "sentence-case" 19 | } 20 | ], 21 | "initial-version": "2.7.2" 22 | } -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base", 4 | "group:all", 5 | ":preserveSemverRanges", 6 | ":disableDependencyDashboard" 7 | ], 8 | "ignorePaths": [".pre-commit-config.yaml", ".kokoro/requirements.txt", "setup.py", ".github/workflows/*"], 9 | "pip_requirements": { 10 | "fileMatch": ["requirements-test.txt", "samples/[\\S/]*constraints.txt", "samples/[\\S/]*constraints-test.txt"] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/AUTHORING_GUIDE.md: -------------------------------------------------------------------------------- 1 | See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/AUTHORING_GUIDE.md -------------------------------------------------------------------------------- /samples/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | See https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/CONTRIBUTING.md -------------------------------------------------------------------------------- /scripts/readme-gen/templates/auth.tmpl.rst: -------------------------------------------------------------------------------- 1 | Authentication 2 | ++++++++++++++ 3 | 4 | This sample requires you to have authentication setup. Refer to the 5 | `Authentication Getting Started Guide`_ for instructions on setting up 6 | credentials for applications. 7 | 8 | .. _Authentication Getting Started Guide: 9 | https://cloud.google.com/docs/authentication/getting-started 10 | -------------------------------------------------------------------------------- /scripts/readme-gen/templates/auth_api_key.tmpl.rst: -------------------------------------------------------------------------------- 1 | Authentication 2 | ++++++++++++++ 3 | 4 | Authentication for this service is done via an `API Key`_. To obtain an API 5 | Key: 6 | 7 | 1. Open the `Cloud Platform Console`_ 8 | 2. Make sure that billing is enabled for your project. 9 | 3. From the **Credentials** page, create a new **API Key** or use an existing 10 | one for your project. 11 | 12 | .. _API Key: 13 | https://developers.google.com/api-client-library/python/guide/aaa_apikeys 14 | .. _Cloud Console: https://console.cloud.google.com/project?_ 15 | -------------------------------------------------------------------------------- /scripts/readme-gen/templates/install_deps.tmpl.rst: -------------------------------------------------------------------------------- 1 | Install Dependencies 2 | ++++++++++++++++++++ 3 | 4 | #. Clone python-docs-samples and change directory to the sample directory you want to use. 5 | 6 | .. code-block:: bash 7 | 8 | $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git 9 | 10 | #. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. 11 | 12 | .. _Python Development Environment Setup Guide: 13 | https://cloud.google.com/python/setup 14 | 15 | #. Create a virtualenv. Samples are compatible with Python 3.7+. 16 | 17 | .. code-block:: bash 18 | 19 | $ virtualenv env 20 | $ source env/bin/activate 21 | 22 | #. Install the dependencies needed to run the samples. 23 | 24 | .. code-block:: bash 25 | 26 | $ pip install -r requirements.txt 27 | 28 | .. _pip: https://pip.pypa.io/ 29 | .. _virtualenv: https://virtualenv.pypa.io/ 30 | -------------------------------------------------------------------------------- /scripts/readme-gen/templates/install_portaudio.tmpl.rst: -------------------------------------------------------------------------------- 1 | Install PortAudio 2 | +++++++++++++++++ 3 | 4 | Install `PortAudio`_. This is required by the `PyAudio`_ library to stream 5 | audio from your computer's microphone. PyAudio depends on PortAudio for cross-platform compatibility, and is installed differently depending on the 6 | platform. 7 | 8 | * For Mac OS X, you can use `Homebrew`_:: 9 | 10 | brew install portaudio 11 | 12 | **Note**: if you encounter an error when running `pip install` that indicates 13 | it can't find `portaudio.h`, try running `pip install` with the following 14 | flags:: 15 | 16 | pip install --global-option='build_ext' \ 17 | --global-option='-I/usr/local/include' \ 18 | --global-option='-L/usr/local/lib' \ 19 | pyaudio 20 | 21 | * For Debian / Ubuntu Linux:: 22 | 23 | apt-get install portaudio19-dev python-all-dev 24 | 25 | * Windows may work without having to install PortAudio explicitly (it will get 26 | installed with PyAudio). 27 | 28 | For more details, see the `PyAudio installation`_ page. 29 | 30 | 31 | .. _PyAudio: https://people.csail.mit.edu/hubert/pyaudio/ 32 | .. _PortAudio: http://www.portaudio.com/ 33 | .. _PyAudio installation: 34 | https://people.csail.mit.edu/hubert/pyaudio/#downloads 35 | .. _Homebrew: http://brew.sh 36 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright 2023 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | [pytype] 18 | python_version = 3.8 19 | inputs = 20 | google/cloud/ 21 | exclude = 22 | tests/ 23 | output = .pytype/ 24 | # Workaround for https://github.com/google/pytype/issues/150 25 | disable = pyi-error 26 | -------------------------------------------------------------------------------- /testing/.gitignore: -------------------------------------------------------------------------------- 1 | test-env.sh 2 | service-account.json 3 | client-secrets.json -------------------------------------------------------------------------------- /testing/constraints-3.10.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/python-firestore/d8e3af1f9dbdfaf5df0d993a0a7e28883472c621/testing/constraints-3.10.txt -------------------------------------------------------------------------------- /testing/constraints-3.11.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/python-firestore/d8e3af1f9dbdfaf5df0d993a0a7e28883472c621/testing/constraints-3.11.txt -------------------------------------------------------------------------------- /testing/constraints-3.12.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/python-firestore/d8e3af1f9dbdfaf5df0d993a0a7e28883472c621/testing/constraints-3.12.txt -------------------------------------------------------------------------------- /testing/constraints-3.13.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/python-firestore/d8e3af1f9dbdfaf5df0d993a0a7e28883472c621/testing/constraints-3.13.txt -------------------------------------------------------------------------------- /testing/constraints-3.7.txt: -------------------------------------------------------------------------------- 1 | # This constraints file is used to check that lower bounds 2 | # are correct in setup.py 3 | # List *all* library dependencies and extras in this file. 4 | # Pin the version to the lower bound. 5 | # 6 | # e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev", 7 | # Then this file should have foo==1.14.0 8 | google-api-core==1.34.0 9 | google-auth==2.14.1 10 | google-cloud-core==1.4.1 11 | proto-plus==1.22.0 12 | protobuf==3.20.2 # transitive from `google-api-core` 13 | -------------------------------------------------------------------------------- /testing/constraints-3.8.txt: -------------------------------------------------------------------------------- 1 | google-api-core==2.14.0 2 | -------------------------------------------------------------------------------- /testing/constraints-3.9.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/python-firestore/d8e3af1f9dbdfaf5df0d993a0a7e28883472c621/testing/constraints-3.9.txt -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | -------------------------------------------------------------------------------- /tests/system/test__helpers.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | 4 | from test_utils.system import EmulatorCreds, unique_resource_id 5 | 6 | from google.cloud.firestore_v1.base_client import _FIRESTORE_EMULATOR_HOST 7 | 8 | FIRESTORE_CREDS = os.environ.get("FIRESTORE_APPLICATION_CREDENTIALS") 9 | FIRESTORE_PROJECT = os.environ.get("GCLOUD_PROJECT") 10 | RANDOM_ID_REGEX = re.compile("^[a-zA-Z0-9]{20}$") 11 | MISSING_DOCUMENT = "No document to update: " 12 | DOCUMENT_EXISTS = "Document already exists: " 13 | UNIQUE_RESOURCE_ID = unique_resource_id("-") 14 | EMULATOR_CREDS = EmulatorCreds() 15 | FIRESTORE_EMULATOR = os.environ.get(_FIRESTORE_EMULATOR_HOST) is not None 16 | FIRESTORE_OTHER_DB = os.environ.get("SYSTEM_TESTS_DATABASE", "system-tests-named-db") 17 | -------------------------------------------------------------------------------- /tests/system/util/cleanup_firestore_documents.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | """Clean up documents leaked by system tests.""" 15 | from google.cloud.firestore import Client 16 | 17 | 18 | def zap_document(document): 19 | print("Zapping document: {}".format(document.path)) 20 | for collection in document.collections(): 21 | zap_collection(collection) 22 | document.delete() 23 | 24 | 25 | def zap_collection(collection): 26 | for document in collection.list_documents(): 27 | zap_document(document) 28 | 29 | 30 | def main(): 31 | client = Client() 32 | 33 | for collection in client.collections(): 34 | zap_collection(collection) 35 | 36 | 37 | if __name__ == "__main__": 38 | main() 39 | -------------------------------------------------------------------------------- /tests/unit/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | -------------------------------------------------------------------------------- /tests/unit/gapic/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | -------------------------------------------------------------------------------- /tests/unit/gapic/bundle/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | -------------------------------------------------------------------------------- /tests/unit/gapic/firestore_admin_v1/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | -------------------------------------------------------------------------------- /tests/unit/gapic/firestore_v1/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Copyright 2025 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | -------------------------------------------------------------------------------- /tests/unit/gapic/v1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/python-firestore/d8e3af1f9dbdfaf5df0d993a0a7e28883472c621/tests/unit/gapic/v1/__init__.py -------------------------------------------------------------------------------- /tests/unit/v1/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-arrayremove-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ArrayRemove cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-arrayremove-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ArrayRemove cannot be in an array value", 5 | "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-arrayremove-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayRemove\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-arrayunion-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ArrayUnion cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-arrayunion-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ArrayUnion cannot be in an array value", 5 | "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-arrayunion-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayUnion\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: basic", 5 | "comment": "A simple call, resulting in a single update operation.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "currentDocument": { 22 | "exists": false 23 | } 24 | } 25 | ] 26 | } 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-del-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: Delete cannot be anywhere inside an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"Delete\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-del-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: Delete cannot be in an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"Delete\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: creating or setting an empty map", 5 | "create": { 6 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 7 | "jsonData": "{}", 8 | "request": { 9 | "database": "projects/projectID/databases/(default)", 10 | "writes": [ 11 | { 12 | "update": { 13 | "name": "projects/projectID/databases/(default)/documents/C/d", 14 | "fields": {} 15 | }, 16 | "currentDocument": { 17 | "exists": false 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-nodel.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: Delete cannot appear in data", 5 | "comment": "The Delete sentinel cannot be used in Create, or in Set without a Merge option.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-nosplit.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: don’t split on dots", 5 | "comment": "Create and Set treat their map keys literally. They do not split on dots.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{ \"a.b\": { \"c.d\": 1 }, \"e\": 2 }", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a.b": { 17 | "mapValue": { 18 | "fields": { 19 | "c.d": { 20 | "integerValue": "1" 21 | } 22 | } 23 | } 24 | }, 25 | "e": { 26 | "integerValue": "2" 27 | } 28 | } 29 | }, 30 | "currentDocument": { 31 | "exists": false 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-special-chars.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: non-alpha characters in map keys", 5 | "comment": "Create and Set treat their map keys literally. They do not escape special characters.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{ \"*\": { \".\": 1 }, \"~\": 2 }", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "*": { 17 | "mapValue": { 18 | "fields": { 19 | ".": { 20 | "integerValue": "1" 21 | } 22 | } 23 | } 24 | }, 25 | "~": { 26 | "integerValue": "2" 27 | } 28 | } 29 | }, 30 | "currentDocument": { 31 | "exists": false 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-st-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ServerTimestamp alone", 5 | "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "currentDocument": { 14 | "exists": false 15 | }, 16 | "update": { 17 | "fields": {}, 18 | "name": "projects/projectID/databases/(default)/documents/C/d" 19 | }, 20 | "updateTransforms": [ 21 | { 22 | "fieldPath": "a", 23 | "setToServerValue": "REQUEST_TIME" 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | } 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-st-multi.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: multiple ServerTimestamp fields", 5 | "comment": "A document can have more than one ServerTimestamp field.\nSince all the ServerTimestamp fields are removed, the only field in the update is \"a\".", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\", \"c\": {\"d\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "currentDocument": { 22 | "exists": false 23 | }, 24 | "updateTransforms": [ 25 | { 26 | "fieldPath": "b", 27 | "setToServerValue": "REQUEST_TIME" 28 | }, 29 | { 30 | "fieldPath": "c.d", 31 | "setToServerValue": "REQUEST_TIME" 32 | } 33 | ] 34 | } 35 | ] 36 | } 37 | } 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-st-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: nested ServerTimestamp field", 5 | "comment": "A ServerTimestamp value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "currentDocument": { 22 | "exists": false 23 | }, 24 | "updateTransforms": [ 25 | { 26 | "fieldPath": "b.c", 27 | "setToServerValue": "REQUEST_TIME" 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-st-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ServerTimestamp cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"ServerTimestamp\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-st-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ServerTimestamp cannot be in an array value", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"ServerTimestamp\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/create-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ServerTimestamp with data", 5 | "comment": "A key with the special ServerTimestamp sentinel is removed from\nthe data in the update operation. Instead it appears in a separate Transform operation.\nNote that in these tests, the string \"ServerTimestamp\" should be replaced with the\nspecial ServerTimestamp value.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "currentDocument": { 22 | "exists": false 23 | }, 24 | "updateTransforms": [ 25 | { 26 | "fieldPath": "b", 27 | "setToServerValue": "REQUEST_TIME" 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/delete-exists-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "delete: delete with exists precondition", 5 | "comment": "Delete supports an exists precondition.", 6 | "delete": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "exists": true 10 | }, 11 | "request": { 12 | "database": "projects/projectID/databases/(default)", 13 | "writes": [ 14 | { 15 | "delete": "projects/projectID/databases/(default)/documents/C/d", 16 | "currentDocument": { 17 | "exists": true 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/delete-no-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "delete: delete without precondition", 5 | "comment": "An ordinary Delete call.", 6 | "delete": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "request": { 9 | "database": "projects/projectID/databases/(default)", 10 | "writes": [ 11 | { 12 | "delete": "projects/projectID/databases/(default)/documents/C/d" 13 | } 14 | ] 15 | } 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/delete-time-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "delete: delete with last-update-time precondition", 5 | "comment": "Delete supports a last-update-time precondition.", 6 | "delete": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "updateTime": "1970-01-01T00:00:42Z" 10 | }, 11 | "request": { 12 | "database": "projects/projectID/databases/(default)", 13 | "writes": [ 14 | { 15 | "delete": "projects/projectID/databases/(default)/documents/C/d", 16 | "currentDocument": { 17 | "updateTime": "1970-01-01T00:00:42Z" 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/get-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "get: get a document", 5 | "comment": "A call to DocumentRef.Get", 6 | "get": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "request": { 9 | "name": "projects/projectID/databases/(default)/documents/C/d" 10 | } 11 | } 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/listen-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "listen: no changes; empty snapshot", 5 | "comment": "There are no changes, so the snapshot should be empty.", 6 | "listen": { 7 | "responses": [ 8 | { 9 | "targetChange": { 10 | "targetChangeType": "CURRENT" 11 | } 12 | }, 13 | { 14 | "targetChange": { 15 | "readTime": "1970-01-01T00:00:01Z" 16 | } 17 | } 18 | ], 19 | "snapshots": [ 20 | { 21 | "readTime": "1970-01-01T00:00:01Z" 22 | } 23 | ] 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/listen-target-remove.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "listen: TargetChange_REMOVE should not appear", 5 | "comment": "A TargetChange_REMOVE response should never be sent.", 6 | "listen": { 7 | "responses": [ 8 | { 9 | "documentChange": { 10 | "document": { 11 | "name": "projects/projectID/databases/(default)/documents/C/d1", 12 | "fields": { 13 | "a": { 14 | "integerValue": "3" 15 | } 16 | }, 17 | "createTime": "1970-01-01T00:00:01Z", 18 | "updateTime": "1970-01-01T00:00:01Z" 19 | }, 20 | "targetIds": [ 21 | 1 22 | ] 23 | } 24 | }, 25 | { 26 | "targetChange": { 27 | "targetChangeType": "CURRENT" 28 | } 29 | }, 30 | { 31 | "targetChange": { 32 | "targetChangeType": "REMOVE" 33 | } 34 | }, 35 | { 36 | "targetChange": { 37 | "readTime": "1970-01-01T00:00:01Z" 38 | } 39 | } 40 | ], 41 | "isError": true 42 | } 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-arrayremove-cursor.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ArrayRemove in cursor method", 5 | "comment": "ArrayRemove is not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": { 21 | "jsonValues": [ 22 | "[\"ArrayRemove\", 1, 2, 3]" 23 | ] 24 | } 25 | } 26 | ], 27 | "isError": true 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-arrayremove-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ArrayRemove in Where", 5 | "comment": "ArrayRemove is not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "[\"ArrayRemove\", 1, 2, 3]" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-arrayunion-cursor.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ArrayUnion in cursor method", 5 | "comment": "ArrayUnion is not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": { 21 | "jsonValues": [ 22 | "[\"ArrayUnion\", 1, 2, 3]" 23 | ] 24 | } 25 | } 26 | ], 27 | "isError": true 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-arrayunion-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ArrayUnion in Where", 5 | "comment": "ArrayUnion is not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "[\"ArrayUnion\", 1, 2, 3]" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-bad-NaN.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: where clause with non-== comparison with NaN", 5 | "comment": "You can only compare NaN for equality.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "\u003c", 17 | "jsonValue": "\"NaN\"" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-bad-null.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: where clause with non-== comparison with Null", 5 | "comment": "You can only compare Null for equality.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "\u003e", 17 | "jsonValue": "null" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-cursor-docsnap.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: cursor methods with a document snapshot", 5 | "comment": "When a document snapshot is used, the client appends a __name__ order-by clause.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "startAt": { 11 | "docSnapshot": { 12 | "path": "projects/projectID/databases/(default)/documents/C/D", 13 | "jsonData": "{\"a\": 7, \"b\": 8}" 14 | } 15 | } 16 | } 17 | ], 18 | "query": { 19 | "from": [ 20 | { 21 | "collectionId": "C" 22 | } 23 | ], 24 | "orderBy": [ 25 | { 26 | "field": { 27 | "fieldPath": "__name__" 28 | }, 29 | "direction": "ASCENDING" 30 | } 31 | ], 32 | "startAt": { 33 | "values": [ 34 | { 35 | "referenceValue": "projects/projectID/databases/(default)/documents/C/D" 36 | } 37 | ], 38 | "before": true 39 | } 40 | } 41 | } 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-cursor-endbefore-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: EndBefore with empty values", 5 | "comment": "Cursor methods are not allowed to use empty values with EndBefore. It should result in an error.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": {} 21 | } 22 | ], 23 | "isError": true 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-cursor-no-order.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: cursor method without orderBy", 5 | "comment": "If a cursor method with a list of values is provided, there must be at least as many\nexplicit orderBy clauses as values.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "startAt": { 11 | "jsonValues": [ 12 | "2" 13 | ] 14 | } 15 | } 16 | ], 17 | "isError": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-cursor-startat-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: StartAt with empty values", 5 | "comment": "Cursor methods are not allowed to use empty values with StartAt. It should result in an error.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "startAt": {} 21 | } 22 | ], 23 | "isError": true 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-del-cursor.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: Delete in cursor method", 5 | "comment": "Sentinel values are not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": { 21 | "jsonValues": [ 22 | "\"Delete\"" 23 | ] 24 | } 25 | } 26 | ], 27 | "isError": true 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-del-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: Delete in Where", 5 | "comment": "Sentinel values are not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "\"Delete\"" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-invalid-operator.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: invalid operator in Where clause", 5 | "comment": "The |~| operator is not supported.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "|~|", 17 | "jsonValue": "4" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-invalid-path-order.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: invalid path in OrderBy clause", 5 | "comment": "The path has an empty component.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "*", 14 | "" 15 | ] 16 | }, 17 | "direction": "asc" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-invalid-path-select.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: invalid path in Where clause", 5 | "comment": "The path has an empty component.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "select": { 11 | "fields": [ 12 | { 13 | "field": [ 14 | "*", 15 | "" 16 | ] 17 | } 18 | ] 19 | } 20 | } 21 | ], 22 | "isError": true 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-invalid-path-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: invalid path in Where clause", 5 | "comment": "The path has an empty component.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "*", 14 | "" 15 | ] 16 | }, 17 | "op": "==", 18 | "jsonValue": "4" 19 | } 20 | } 21 | ], 22 | "isError": true 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-offset-limit-last-wins.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: multiple Offset and Limit clauses", 5 | "comment": "With multiple Offset or Limit clauses, the last one wins.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "offset": 2 11 | }, 12 | { 13 | "limit": 3 14 | }, 15 | { 16 | "limit": 4 17 | }, 18 | { 19 | "offset": 5 20 | } 21 | ], 22 | "query": { 23 | "from": [ 24 | { 25 | "collectionId": "C" 26 | } 27 | ], 28 | "offset": 5, 29 | "limit": 4 30 | } 31 | } 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-offset-limit.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: Offset and Limit clauses", 5 | "comment": "Offset and Limit clauses.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "offset": 2 11 | }, 12 | { 13 | "limit": 3 14 | } 15 | ], 16 | "query": { 17 | "from": [ 18 | { 19 | "collectionId": "C" 20 | } 21 | ], 22 | "offset": 2, 23 | "limit": 3 24 | } 25 | } 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-order.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: basic OrderBy clauses", 5 | "comment": "Multiple OrderBy clauses combine.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "b" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "orderBy": { 21 | "path": { 22 | "field": [ 23 | "a" 24 | ] 25 | }, 26 | "direction": "desc" 27 | } 28 | } 29 | ], 30 | "query": { 31 | "from": [ 32 | { 33 | "collectionId": "C" 34 | } 35 | ], 36 | "orderBy": [ 37 | { 38 | "field": { 39 | "fieldPath": "b" 40 | }, 41 | "direction": "ASCENDING" 42 | }, 43 | { 44 | "field": { 45 | "fieldPath": "a" 46 | }, 47 | "direction": "DESCENDING" 48 | } 49 | ] 50 | } 51 | } 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-select-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: empty Select clause", 5 | "comment": "An empty Select clause selects just the document ID.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "select": { 11 | "fields": [] 12 | } 13 | } 14 | ], 15 | "query": { 16 | "select": { 17 | "fields": [ 18 | { 19 | "fieldPath": "__name__" 20 | } 21 | ] 22 | }, 23 | "from": [ 24 | { 25 | "collectionId": "C" 26 | } 27 | ] 28 | } 29 | } 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-select-last-wins.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: two Select clauses", 5 | "comment": "The last Select clause is the only one used.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "select": { 11 | "fields": [ 12 | { 13 | "field": [ 14 | "a" 15 | ] 16 | }, 17 | { 18 | "field": [ 19 | "b" 20 | ] 21 | } 22 | ] 23 | } 24 | }, 25 | { 26 | "select": { 27 | "fields": [ 28 | { 29 | "field": [ 30 | "c" 31 | ] 32 | } 33 | ] 34 | } 35 | } 36 | ], 37 | "query": { 38 | "select": { 39 | "fields": [ 40 | { 41 | "fieldPath": "c" 42 | } 43 | ] 44 | }, 45 | "from": [ 46 | { 47 | "collectionId": "C" 48 | } 49 | ] 50 | } 51 | } 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-select.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: Select clause with some fields", 5 | "comment": "An ordinary Select clause.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "select": { 11 | "fields": [ 12 | { 13 | "field": [ 14 | "a" 15 | ] 16 | }, 17 | { 18 | "field": [ 19 | "b" 20 | ] 21 | } 22 | ] 23 | } 24 | } 25 | ], 26 | "query": { 27 | "select": { 28 | "fields": [ 29 | { 30 | "fieldPath": "a" 31 | }, 32 | { 33 | "fieldPath": "b" 34 | } 35 | ] 36 | }, 37 | "from": [ 38 | { 39 | "collectionId": "C" 40 | } 41 | ] 42 | } 43 | } 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-st-cursor.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ServerTimestamp in cursor method", 5 | "comment": "Sentinel values are not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": { 21 | "jsonValues": [ 22 | "\"ServerTimestamp\"" 23 | ] 24 | } 25 | } 26 | ], 27 | "isError": true 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-st-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ServerTimestamp in Where", 5 | "comment": "Sentinel values are not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "\"ServerTimestamp\"" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-where-NaN.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: a Where clause comparing to NaN", 5 | "comment": "A Where clause that tests for equality with NaN results in a unary filter.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "\"NaN\"" 18 | } 19 | } 20 | ], 21 | "query": { 22 | "from": [ 23 | { 24 | "collectionId": "C" 25 | } 26 | ], 27 | "where": { 28 | "unaryFilter": { 29 | "op": "IS_NAN", 30 | "field": { 31 | "fieldPath": "a" 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-where-null.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: a Where clause comparing to null", 5 | "comment": "A Where clause that tests for equality with null results in a unary filter.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "null" 18 | } 19 | } 20 | ], 21 | "query": { 22 | "from": [ 23 | { 24 | "collectionId": "C" 25 | } 26 | ], 27 | "where": { 28 | "unaryFilter": { 29 | "op": "IS_NULL", 30 | "field": { 31 | "fieldPath": "a" 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: Where clause", 5 | "comment": "A simple Where clause.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "\u003e", 17 | "jsonValue": "5" 18 | } 19 | } 20 | ], 21 | "query": { 22 | "from": [ 23 | { 24 | "collectionId": "C" 25 | } 26 | ], 27 | "where": { 28 | "fieldFilter": { 29 | "field": { 30 | "fieldPath": "a" 31 | }, 32 | "op": "GREATER_THAN", 33 | "value": { 34 | "integerValue": "5" 35 | } 36 | } 37 | } 38 | } 39 | } 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/query-wrong-collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: doc snapshot with wrong collection in cursor method", 5 | "comment": "If a document snapshot is passed to a Start*/End* method, it must be in the\nsame collection as the query.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "endBefore": { 11 | "docSnapshot": { 12 | "path": "projects/projectID/databases/(default)/documents/C2/D", 13 | "jsonData": "{\"a\": 7, \"b\": 8}" 14 | } 15 | } 16 | } 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-arrayremove-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ArrayRemove cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-arrayremove-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ArrayRemove cannot be in an array value", 5 | "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-arrayremove-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayRemove\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-arrayunion-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ArrayUnion cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-arrayunion-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ArrayUnion cannot be in an array value", 5 | "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-arrayunion-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayUnion\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: basic", 5 | "comment": "A simple call, resulting in a single update operation.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | } 21 | } 22 | ] 23 | } 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-del-merge-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Delete with merge", 5 | "comment": "A Delete sentinel can appear with a merge option. If the delete\npaths are the only ones to be merged, then no document is sent, just an update mask.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "b", 13 | "c" 14 | ] 15 | } 16 | ] 17 | }, 18 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"Delete\"}}", 19 | "request": { 20 | "database": "projects/projectID/databases/(default)", 21 | "writes": [ 22 | { 23 | "update": { 24 | "name": "projects/projectID/databases/(default)/documents/C/d" 25 | }, 26 | "updateMask": { 27 | "fieldPaths": [ 28 | "b.c" 29 | ] 30 | } 31 | } 32 | ] 33 | } 34 | } 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-del-merge.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Delete with merge", 5 | "comment": "A Delete sentinel can appear with a merge option.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "a" 13 | ] 14 | }, 15 | { 16 | "field": [ 17 | "b", 18 | "c" 19 | ] 20 | } 21 | ] 22 | }, 23 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"Delete\"}}", 24 | "request": { 25 | "database": "projects/projectID/databases/(default)", 26 | "writes": [ 27 | { 28 | "update": { 29 | "name": "projects/projectID/databases/(default)/documents/C/d", 30 | "fields": { 31 | "a": { 32 | "integerValue": "1" 33 | } 34 | } 35 | }, 36 | "updateMask": { 37 | "fieldPaths": [ 38 | "a", 39 | "b.c" 40 | ] 41 | } 42 | } 43 | ] 44 | } 45 | } 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-del-mergeall.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: Delete with MergeAll", 5 | "comment": "A Delete sentinel can appear with a mergeAll option.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"Delete\"}}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": { 19 | "a": { 20 | "integerValue": "1" 21 | } 22 | } 23 | }, 24 | "updateMask": { 25 | "fieldPaths": [ 26 | "a", 27 | "b.c" 28 | ] 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-del-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: Delete cannot be anywhere inside an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"Delete\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-del-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: Delete cannot be in an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"Delete\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-del-nomerge.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Delete cannot appear in an unmerged field", 5 | "comment": "The client signals an error if the Delete sentinel is in the\ninput data, but not selected by a merge option, because this is most likely a programming\nbug.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "a" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-del-nonleaf.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Delete cannot appear as part of a merge path", 5 | "comment": "If a Delete is part of the value at a merge path, then the user is\nconfused: their merge path says \"replace this entire value\" but their Delete says\n\"delete this part of the value\". This should be an error, just as if they specified Delete\nin a Set with no merge.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "h" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"h\": {\"g\": \"Delete\"}}", 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-del-wo-merge.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: Delete cannot appear unless a merge option is specified", 5 | "comment": "Without a merge option, Set replaces the document with the input\ndata. A Delete sentinel in the data makes no sense in this case.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: creating or setting an empty map", 5 | "set": { 6 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 7 | "jsonData": "{}", 8 | "request": { 9 | "database": "projects/projectID/databases/(default)", 10 | "writes": [ 11 | { 12 | "update": { 13 | "name": "projects/projectID/databases/(default)/documents/C/d", 14 | "fields": {} 15 | } 16 | } 17 | ] 18 | } 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-merge-fp.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Merge with FieldPaths", 5 | "comment": "A merge with fields that use special characters.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "*", 13 | "~" 14 | ] 15 | } 16 | ] 17 | }, 18 | "jsonData": "{\"*\": {\"~\": true}}", 19 | "request": { 20 | "database": "projects/projectID/databases/(default)", 21 | "writes": [ 22 | { 23 | "update": { 24 | "name": "projects/projectID/databases/(default)/documents/C/d", 25 | "fields": { 26 | "*": { 27 | "mapValue": { 28 | "fields": { 29 | "~": { 30 | "booleanValue": true 31 | } 32 | } 33 | } 34 | } 35 | } 36 | }, 37 | "updateMask": { 38 | "fieldPaths": [ 39 | "`*`.`~`" 40 | ] 41 | } 42 | } 43 | ] 44 | } 45 | } 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-merge-prefix.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: One merge path cannot be the prefix of another", 5 | "comment": "The prefix would make the other path meaningless, so this is\nprobably a programming error.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "a" 13 | ] 14 | }, 15 | { 16 | "field": [ 17 | "a", 18 | "b" 19 | ] 20 | } 21 | ] 22 | }, 23 | "jsonData": "{\"a\": {\"b\": 1}}", 24 | "isError": true 25 | } 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-merge-present.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Merge fields must all be present in data", 5 | "comment": "The client signals an error if a merge option mentions a path\nthat is not in the input data.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "b" 13 | ] 14 | }, 15 | { 16 | "field": [ 17 | "a" 18 | ] 19 | } 20 | ] 21 | }, 22 | "jsonData": "{\"a\": 1}", 23 | "isError": true 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-merge.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Merge with a field", 5 | "comment": "Fields in the input data but not in a merge option are pruned.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "a" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"a\": 1, \"b\": 2}", 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "name": "projects/projectID/databases/(default)/documents/C/d", 24 | "fields": { 25 | "a": { 26 | "integerValue": "1" 27 | } 28 | } 29 | }, 30 | "updateMask": { 31 | "fieldPaths": [ 32 | "a" 33 | ] 34 | } 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-mergeall-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: MergeAll can be specified with empty data.", 5 | "comment": "This is a valid call that can be used to ensure a document exists.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": {} 19 | }, 20 | "updateMask": { 21 | "fieldPaths": [] 22 | } 23 | } 24 | ] 25 | } 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-mergeall.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: MergeAll", 5 | "comment": "The MergeAll option with a simple piece of data.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{\"a\": 1, \"b\": 2}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": { 19 | "a": { 20 | "integerValue": "1" 21 | }, 22 | "b": { 23 | "integerValue": "2" 24 | } 25 | } 26 | }, 27 | "updateMask": { 28 | "fieldPaths": [ 29 | "a", 30 | "b" 31 | ] 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-nodel.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: Delete cannot appear in data", 5 | "comment": "The Delete sentinel cannot be used in Create, or in Set without a Merge option.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-nosplit.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: don’t split on dots", 5 | "comment": "Create and Set treat their map keys literally. They do not split on dots.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{ \"a.b\": { \"c.d\": 1 }, \"e\": 2 }", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a.b": { 17 | "mapValue": { 18 | "fields": { 19 | "c.d": { 20 | "integerValue": "1" 21 | } 22 | } 23 | } 24 | }, 25 | "e": { 26 | "integerValue": "2" 27 | } 28 | } 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-special-chars.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: non-alpha characters in map keys", 5 | "comment": "Create and Set treat their map keys literally. They do not escape special characters.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{ \"*\": { \".\": 1 }, \"~\": 2 }", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "*": { 17 | "mapValue": { 18 | "fields": { 19 | ".": { 20 | "integerValue": "1" 21 | } 22 | } 23 | } 24 | }, 25 | "~": { 26 | "integerValue": "2" 27 | } 28 | } 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st-alone-mergeall.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp alone with MergeAll", 5 | "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{\"a\": \"ServerTimestamp\"}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "fields": {}, 18 | "name": "projects/projectID/databases/(default)/documents/C/d" 19 | }, 20 | "updateMask": { 21 | "fieldPaths": [] 22 | }, 23 | "updateTransforms": [ 24 | { 25 | "fieldPath": "a", 26 | "setToServerValue": "REQUEST_TIME" 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp alone", 5 | "comment": "If the only values in the input are ServerTimestamps, then\nan update operation with an empty map should be produced.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": {} 16 | }, 17 | "updateTransforms": [ 18 | { 19 | "fieldPath": "a", 20 | "setToServerValue": "REQUEST_TIME" 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st-merge-nowrite.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: If no ordinary values in Merge, no write", 5 | "comment": "If all the fields in the merge option have ServerTimestamp\nvalues, then no update operation is produced, only a transform.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "b" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "fields": {}, 24 | "name": "projects/projectID/databases/(default)/documents/C/d" 25 | }, 26 | "updateMask": { 27 | "fieldPaths": [] 28 | }, 29 | "updateTransforms": [ 30 | { 31 | "fieldPath": "b", 32 | "setToServerValue": "REQUEST_TIME" 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st-mergeall.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp with MergeAll", 5 | "comment": "Just as when no merge option is specified, ServerTimestamp\nsentinel values are removed from the data in the update operation and become\ntransforms.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": { 19 | "a": { 20 | "integerValue": "1" 21 | } 22 | } 23 | }, 24 | "updateMask": { 25 | "fieldPaths": [ 26 | "a" 27 | ] 28 | }, 29 | "updateTransforms": [ 30 | { 31 | "fieldPath": "b", 32 | "setToServerValue": "REQUEST_TIME" 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st-multi.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: multiple ServerTimestamp fields", 5 | "comment": "A document can have more than one ServerTimestamp field.\nSince all the ServerTimestamp fields are removed, the only field in the update is \"a\".", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\", \"c\": {\"d\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateTransforms": [ 22 | { 23 | "fieldPath": "b", 24 | "setToServerValue": "REQUEST_TIME" 25 | }, 26 | { 27 | "fieldPath": "c.d", 28 | "setToServerValue": "REQUEST_TIME" 29 | } 30 | ] 31 | } 32 | ] 33 | } 34 | } 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: nested ServerTimestamp field", 5 | "comment": "A ServerTimestamp value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateTransforms": [ 22 | { 23 | "fieldPath": "b.c", 24 | "setToServerValue": "REQUEST_TIME" 25 | } 26 | ] 27 | } 28 | ] 29 | } 30 | } 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"ServerTimestamp\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp cannot be in an array value", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"ServerTimestamp\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st-nomerge.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: If is ServerTimestamp not in Merge, no transform", 5 | "comment": "If the ServerTimestamp value is not mentioned in a merge option,\nthen it is pruned from the data but does not result in a transform.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "a" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "name": "projects/projectID/databases/(default)/documents/C/d", 24 | "fields": { 25 | "a": { 26 | "integerValue": "1" 27 | } 28 | } 29 | }, 30 | "updateMask": { 31 | "fieldPaths": [ 32 | "a" 33 | ] 34 | } 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st-with-empty-map.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp beside an empty map", 5 | "comment": "When a ServerTimestamp and a map both reside inside a map, the\nServerTimestamp should be stripped out but the empty map should remain.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": {\"b\": {}, \"c\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "mapValue": { 18 | "fields": { 19 | "b": { 20 | "mapValue": { 21 | "fields": {} 22 | } 23 | } 24 | } 25 | } 26 | } 27 | } 28 | }, 29 | "updateTransforms": [ 30 | { 31 | "fieldPath": "a.c", 32 | "setToServerValue": "REQUEST_TIME" 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/set-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp with data", 5 | "comment": "A key with the special ServerTimestamp sentinel is removed from\nthe data in the update operation. Instead it appears in a separate Transform operation.\nNote that in these tests, the string \"ServerTimestamp\" should be replaced with the\nspecial ServerTimestamp value.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateTransforms": [ 22 | { 23 | "fieldPath": "b", 24 | "setToServerValue": "REQUEST_TIME" 25 | } 26 | ] 27 | } 28 | ] 29 | } 30 | } 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-arrayremove-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ArrayRemove cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-arrayremove-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ArrayRemove cannot be in an array value", 5 | "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-arrayremove-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayRemove\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-arrayunion-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ArrayUnion cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-arrayunion-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ArrayUnion cannot be in an array value", 5 | "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-arrayunion-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayUnion\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-badchar.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: invalid character", 5 | "comment": "The keys of the data given to Update are interpreted, unlike those of Create and Set. They cannot contain special characters.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a~b\": 1}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: basic", 5 | "comment": "A simple call, resulting in a single update operation.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateMask": { 22 | "fieldPaths": [ 23 | "a" 24 | ] 25 | }, 26 | "currentDocument": { 27 | "exists": true 28 | } 29 | } 30 | ] 31 | } 32 | } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-del-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete alone", 5 | "comment": "If the input data consists solely of Deletes, then the update\noperation has no map, just an update mask.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": \"Delete\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d" 15 | }, 16 | "updateMask": { 17 | "fieldPaths": [ 18 | "a" 19 | ] 20 | }, 21 | "currentDocument": { 22 | "exists": true 23 | } 24 | } 25 | ] 26 | } 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-del-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete cannot be nested", 5 | "comment": "The Delete sentinel must be the value of a top-level key.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": {\"b\": \"Delete\"}}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-del-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete cannot be anywhere inside an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"Delete\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-del-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete cannot be in an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"Delete\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-del.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete", 5 | "comment": "If a field's value is the Delete sentinel, then it doesn't appear\nin the update data, but does in the mask.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateMask": { 22 | "fieldPaths": [ 23 | "a", 24 | "b" 25 | ] 26 | }, 27 | "currentDocument": { 28 | "exists": true 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-exists-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Exists precondition is invalid", 5 | "comment": "The Update method does not support an explicit exists precondition.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "exists": true 10 | }, 11 | "jsonData": "{\"a\": 1}", 12 | "isError": true 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-fp-empty-component.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: empty field path component", 5 | "comment": "Empty fields are not allowed.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a..b\": 1}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-no-paths.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: no paths", 5 | "comment": "It is a client-side error to call Update with empty data.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-arrayremove-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ArrayRemove cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-arrayremove-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ArrayRemove cannot be in an array value", 5 | "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, 2, [\"ArrayRemove\", 1, 2, 3]]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-arrayremove-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[\"ArrayRemove\", 1, \"ServerTimestamp\", 3]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-arrayunion-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ArrayUnion cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-arrayunion-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ArrayUnion cannot be in an array value", 5 | "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, 2, [\"ArrayRemove\", 1, 2, 3]]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-arrayunion-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[\"ArrayUnion\", 1, \"ServerTimestamp\", 3]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: basic", 5 | "comment": "A simple call, resulting in a single update operation.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "1" 17 | ], 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "name": "projects/projectID/databases/(default)/documents/C/d", 24 | "fields": { 25 | "a": { 26 | "integerValue": "1" 27 | } 28 | } 29 | }, 30 | "updateMask": { 31 | "fieldPaths": [ 32 | "a" 33 | ] 34 | }, 35 | "currentDocument": { 36 | "exists": true 37 | } 38 | } 39 | ] 40 | } 41 | } 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-del-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Delete alone", 5 | "comment": "If the input data consists solely of Deletes, then the update\noperation has no map, just an update mask.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "\"Delete\"" 17 | ], 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "name": "projects/projectID/databases/(default)/documents/C/d" 24 | }, 25 | "updateMask": { 26 | "fieldPaths": [ 27 | "a" 28 | ] 29 | }, 30 | "currentDocument": { 31 | "exists": true 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-del-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Delete cannot be nested", 5 | "comment": "The Delete sentinel must be the value of a top-level key.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "{\"b\": \"Delete\"}" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-del-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Delete cannot be anywhere inside an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, {\"b\": \"Delete\"}]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-del-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Delete cannot be in an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, 2, \"Delete\"]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-del.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Delete", 5 | "comment": "If a field's value is the Delete sentinel, then it doesn't appear\nin the update data, but does in the mask.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | }, 14 | { 15 | "field": [ 16 | "b" 17 | ] 18 | } 19 | ], 20 | "jsonValues": [ 21 | "1", 22 | "\"Delete\"" 23 | ], 24 | "request": { 25 | "database": "projects/projectID/databases/(default)", 26 | "writes": [ 27 | { 28 | "update": { 29 | "name": "projects/projectID/databases/(default)/documents/C/d", 30 | "fields": { 31 | "a": { 32 | "integerValue": "1" 33 | } 34 | } 35 | }, 36 | "updateMask": { 37 | "fieldPaths": [ 38 | "a", 39 | "b" 40 | ] 41 | }, 42 | "currentDocument": { 43 | "exists": true 44 | } 45 | } 46 | ] 47 | } 48 | } 49 | } 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-exists-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Exists precondition is invalid", 5 | "comment": "The Update method does not support an explicit exists precondition.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "exists": true 10 | }, 11 | "fieldPaths": [ 12 | { 13 | "field": [ 14 | "a" 15 | ] 16 | } 17 | ], 18 | "jsonValues": [ 19 | "1" 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-fp-dup-transforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: duplicate field path with only transforms", 5 | "comment": "The same field cannot occur more than once, even if all the operations are transforms.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | }, 14 | { 15 | "field": [ 16 | "b" 17 | ] 18 | }, 19 | { 20 | "field": [ 21 | "a" 22 | ] 23 | } 24 | ], 25 | "jsonValues": [ 26 | "[\"ArrayUnion\", 1, 2, 3]", 27 | "\"ServerTimestamp\"", 28 | "[\"ArrayUnion\", 4, 5, 6]" 29 | ], 30 | "isError": true 31 | } 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-fp-dup.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: duplicate field path", 5 | "comment": "The same field cannot occur more than once.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | }, 14 | { 15 | "field": [ 16 | "b" 17 | ] 18 | }, 19 | { 20 | "field": [ 21 | "a" 22 | ] 23 | } 24 | ], 25 | "jsonValues": [ 26 | "1", 27 | "2", 28 | "3" 29 | ], 30 | "isError": true 31 | } 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-fp-empty-component.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: empty field path component", 5 | "comment": "Empty fields are not allowed.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "*", 12 | "" 13 | ] 14 | } 15 | ], 16 | "jsonValues": [ 17 | "1" 18 | ], 19 | "isError": true 20 | } 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-fp-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: empty field path", 5 | "comment": "A FieldPath of length zero is invalid.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [] 11 | } 12 | ], 13 | "jsonValues": [ 14 | "1" 15 | ], 16 | "isError": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-no-paths.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: no paths", 5 | "comment": "It is a client-side error to call Update with empty data.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "isError": true 9 | } 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-prefix-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: prefix #1", 5 | "comment": "In the input data, one field cannot be a prefix of another.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a", 12 | "b" 13 | ] 14 | }, 15 | { 16 | "field": [ 17 | "a" 18 | ] 19 | } 20 | ], 21 | "jsonValues": [ 22 | "1", 23 | "2" 24 | ], 25 | "isError": true 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-prefix-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: prefix #2", 5 | "comment": "In the input data, one field cannot be a prefix of another.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | }, 14 | { 15 | "field": [ 16 | "a", 17 | "b" 18 | ] 19 | } 20 | ], 21 | "jsonValues": [ 22 | "1", 23 | "2" 24 | ], 25 | "isError": true 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-prefix-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: prefix #3", 5 | "comment": "In the input data, one field cannot be a prefix of another, even if the values could in principle be combined.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | }, 14 | { 15 | "field": [ 16 | "a", 17 | "d" 18 | ] 19 | } 20 | ], 21 | "jsonValues": [ 22 | "{\"b\": 1}", 23 | "2" 24 | ], 25 | "isError": true 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-st-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ServerTimestamp alone", 5 | "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "\"ServerTimestamp\"" 17 | ], 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "currentDocument": { 23 | "exists": true 24 | }, 25 | "update": { 26 | "fields": {}, 27 | "name": "projects/projectID/databases/(default)/documents/C/d" 28 | }, 29 | "updateMask": { 30 | "fieldPaths": [] 31 | }, 32 | "updateTransforms": [ 33 | { 34 | "fieldPath": "a", 35 | "setToServerValue": "REQUEST_TIME" 36 | } 37 | ] 38 | } 39 | ] 40 | } 41 | } 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-st-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ServerTimestamp cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, {\"b\": \"ServerTimestamp\"}]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-st-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ServerTimestamp cannot be in an array value", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, 2, \"ServerTimestamp\"]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-paths-uptime.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: last-update-time precondition", 5 | "comment": "The Update call supports a last-update-time precondition.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "updateTime": "1970-01-01T00:00:42Z" 10 | }, 11 | "fieldPaths": [ 12 | { 13 | "field": [ 14 | "a" 15 | ] 16 | } 17 | ], 18 | "jsonValues": [ 19 | "1" 20 | ], 21 | "request": { 22 | "database": "projects/projectID/databases/(default)", 23 | "writes": [ 24 | { 25 | "update": { 26 | "name": "projects/projectID/databases/(default)/documents/C/d", 27 | "fields": { 28 | "a": { 29 | "integerValue": "1" 30 | } 31 | } 32 | }, 33 | "updateMask": { 34 | "fieldPaths": [ 35 | "a" 36 | ] 37 | }, 38 | "currentDocument": { 39 | "updateTime": "1970-01-01T00:00:42Z" 40 | } 41 | } 42 | ] 43 | } 44 | } 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-prefix-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: prefix #1", 5 | "comment": "In the input data, one field cannot be a prefix of another.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a.b\": 1, \"a\": 2}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-prefix-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: prefix #2", 5 | "comment": "In the input data, one field cannot be a prefix of another.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"a.b\": 2}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-prefix-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: prefix #3", 5 | "comment": "In the input data, one field cannot be a prefix of another, even if the values could in principle be combined.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": {\"b\": 1}, \"a.d\": 2}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-st-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ServerTimestamp alone", 5 | "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "currentDocument": { 14 | "exists": true 15 | }, 16 | "update": { 17 | "fields": {}, 18 | "name": "projects/projectID/databases/(default)/documents/C/d" 19 | }, 20 | "updateMask": { 21 | "fieldPaths": [] 22 | }, 23 | "updateTransforms": [ 24 | { 25 | "fieldPath": "a", 26 | "setToServerValue": "REQUEST_TIME" 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-st-dot.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ServerTimestamp with dotted field", 5 | "comment": "Like other uses of ServerTimestamp, the data is pruned and the\nfield does not appear in the update mask, because it is in the transform. In this case\nAn update operation is produced just to hold the precondition.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a.b.c\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "currentDocument": { 14 | "exists": true 15 | }, 16 | "update": { 17 | "fields": {}, 18 | "name": "projects/projectID/databases/(default)/documents/C/d" 19 | }, 20 | "updateMask": { 21 | "fieldPaths": [] 22 | }, 23 | "updateTransforms": [ 24 | { 25 | "fieldPath": "a.b.c", 26 | "setToServerValue": "REQUEST_TIME" 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-st-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ServerTimestamp cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"ServerTimestamp\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-st-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ServerTimestamp cannot be in an array value", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"ServerTimestamp\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/v1/testdata/update-uptime.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: last-update-time precondition", 5 | "comment": "The Update call supports a last-update-time precondition.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "updateTime": "1970-01-01T00:00:42Z" 10 | }, 11 | "jsonData": "{\"a\": 1}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": { 19 | "a": { 20 | "integerValue": "1" 21 | } 22 | } 23 | }, 24 | "updateMask": { 25 | "fieldPaths": [ 26 | "a" 27 | ] 28 | }, 29 | "currentDocument": { 30 | "updateTime": "1970-01-01T00:00:42Z" 31 | } 32 | } 33 | ] 34 | } 35 | } 36 | } 37 | ] 38 | } 39 | --------------------------------------------------------------------------------