При вызове базы данных Firestore из другого облачного проекта отображается "Ошибка разрешения"

После прочтения каждого вопроса и документации, доступной в Интернете, мы не смогли найти решения, поэтому разместили вопрос здесь.

Наша установка:

  1. Project FB: используется только для Firestore в режиме разработки. Мы хотим получить доступ к данным из этого проекта на нашем внутреннем сервере разработки, размещенном в другом облачном проекте.

  2. Project GCP: проект GCP с приложением, развернутым в GAE, которое выполняет простой вызов get() для документа Project FB. Приложение написано на Python и отлично работает на localhost, но не после его развертывания.

Пример кода Flask, который мы тестируем:

route('/test-fb', methods=['POST', 'GET'])
def test():
    doc = doc_ref.get()
    if doc.exists:
        print(u'Document data: {}'.format(doc.to_dict()))
    else:
        print(u'No such document!')
    return make_response("Firestore worked!")

Заметка:

  1. Это не вопрос правил Firestore, потому что мы используем ключ учетной записи службы. Чтобы быть уверенным на 100% в любом случае, у нас есть правила: всегда верно.

    match /{document=**} {разрешить чтение, запись: если верно

  2. Мы генерируем закрытый ключ учетной записи службы, перейдя в "Настройки -> Учетные записи служб", генерируем новый закрытый ключ. Затем используйте фрагмент кода конфигурации Admin SDK в Python над нашим кодом. Это отлично работает в localhost.

  3. Зная о необходимых разрешениях для учетной записи службы, мы добавили множество разрешений, в том числе "Редактор", "Администратор хранилища" и "Владелец облачного хранилища данных", в учетную запись IAM проекта FB для учетной записи службы GAE проекта GCP (@appspot.gserviceaccount.com)

  4. Все пакеты Firestore, любые другие зависимости обновляются до последней версии.

  5. Создал новые ключи для повторного тестирования. Для Project FB обновлены Учетные данные -> Ограничения ключей и установлены неограниченные, чтобы любые домены могли получить к ним доступ.

  6. Удалил версии, и пробовал снова много раз в разное время дня. Развертывания происходят через запускаемые облачные сборки в Project GCP. Сборки облака успешны. Кроме того, все маршруты работают отлично, кроме того, в котором мы читаем документ Firestore (код выше).

  7. Удалил куки и попробовал разные браузеры.

  8. Вместо использования кода фрагмента также попробовал пакет google-cloud-firestore: https://pypi.org/project/google-cloud-firestore/

  9. Оба проекта находятся в одном месте (многопрофильный офис в США).

Посоветуйте, пожалуйста, что мы можем делать не так и что еще мы можем попробовать? Мы заблудились на этом этапе, и эта простая задача заняла у нас несколько дней, и мы несколько раз перепробовали все варианты вышеперечисленных шагов, чтобы дважды проверить.

Ответ GAE на запрос к серверу:

1 ответ

Решение

Я попробовал это на минимальном примере, и это сработало. Убедитесь, что ваше приложение GAE использует учетные данные приложения по умолчанию.

Развертывание приложения Flask в project-foo с доступом к БД Firestore в project-bar:

main.py

from flask import Flask
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore

app = Flask(__name__)

# Use the application default credentials
cred = credentials.ApplicationDefault()
firebase_admin.initialize_app(cred, {
  'projectId': 'project-bar',
})

db = firestore.client()

@app.route('/test-fb', methods=['POST', 'GET'])
def test():
    doc = db.collection('users').document('123').get()
    if doc.exists:
        print(u'Document data: {}'.format(doc.to_dict()))
    else:
        print(u'No such document!')
    return 'Firestore worked!'

if __name__ == '__main__':

Развернуть приложение в project-foo

gcloud set project project-foo
gcloud app deploy

Визит project-foo.uc.r.appspot.com/test-fb. Как и ожидалось, см. Ошибку в разрешении отказано в журналах.

Дайте project-fooдоступ к учетной записи службы по умолчанию project-barБД Firestore

gcloud set project project-bar
gcloud projects add-iam-policy-binding project-bar \
  --member serviceAccount:project-foo@appspot.gserviceaccount.com \
  --role roles/datastore.user

Подождите несколько минут, чтобы привязка IAM закрепилась, обновите project-foo.uc.r.appspot.com/test-fb. ВидетьFirestore worked!.

Другие вопросы по тегам