При вызове базы данных Firestore из другого облачного проекта отображается "Ошибка разрешения"
После прочтения каждого вопроса и документации, доступной в Интернете, мы не смогли найти решения, поэтому разместили вопрос здесь.
Наша установка:
Project FB: используется только для Firestore в режиме разработки. Мы хотим получить доступ к данным из этого проекта на нашем внутреннем сервере разработки, размещенном в другом облачном проекте.
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!")
Заметка:
Это не вопрос правил Firestore, потому что мы используем ключ учетной записи службы. Чтобы быть уверенным на 100% в любом случае, у нас есть правила: всегда верно.
match /{document=**} {разрешить чтение, запись: если верно
Мы генерируем закрытый ключ учетной записи службы, перейдя в "Настройки -> Учетные записи служб", генерируем новый закрытый ключ. Затем используйте фрагмент кода конфигурации Admin SDK в Python над нашим кодом. Это отлично работает в localhost.
Зная о необходимых разрешениях для учетной записи службы, мы добавили множество разрешений, в том числе "Редактор", "Администратор хранилища" и "Владелец облачного хранилища данных", в учетную запись IAM проекта FB для учетной записи службы GAE проекта GCP (@appspot.gserviceaccount.com)
Все пакеты Firestore, любые другие зависимости обновляются до последней версии.
Создал новые ключи для повторного тестирования. Для Project FB обновлены Учетные данные -> Ограничения ключей и установлены неограниченные, чтобы любые домены могли получить к ним доступ.
Удалил версии, и пробовал снова много раз в разное время дня. Развертывания происходят через запускаемые облачные сборки в Project GCP. Сборки облака успешны. Кроме того, все маршруты работают отлично, кроме того, в котором мы читаем документ Firestore (код выше).
Удалил куки и попробовал разные браузеры.
Вместо использования кода фрагмента также попробовал пакет google-cloud-firestore: https://pypi.org/project/google-cloud-firestore/
Оба проекта находятся в одном месте (многопрофильный офис в США).
Посоветуйте, пожалуйста, что мы можем делать не так и что еще мы можем попробовать? Мы заблудились на этом этапе, и эта простая задача заняла у нас несколько дней, и мы несколько раз перепробовали все варианты вышеперечисленных шагов, чтобы дважды проверить.
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!
.