Firestore: транзакции, дающие разрешение, отклонены
Мы обращаемся к Firestore из нашего экземпляра Java-движка приложений.
Нетранзакционные запросы выполняются нормально, но транзакции завершаются с ошибкой:firestore: PERMISSION_DENIED: Missing or insufficient permissions
Пример транзакции
final long updatedValue = 15;
Firestore db = firebaseManager.getFirestore();
CollectionReference fooCollectionRef = db.collection(SOME_COLLECTION);
DocumentReference fooDocumentRef = fooCollectionRef.document(fooId);
final ApiFuture<Long> future = db.runTransaction(transaction -> {
DocumentSnapshot snapshot = transaction.get(fooDocumentRef).get();
transaction.update(fooDocumentRef, SOME_FIELD, updatedValue);
return updatedValue;
});
return future.get();
Насколько я могу судить, наши разрешения на проект dev полностью открыты:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;
}
}
}
Из того, что я прочитал, разрешение записи должно также позволять работать обновлениям транзакций, но ни они, ни вызовы sime get не работают.
Кто-нибудь знает, если я пропускаю шаг / неправильно настроены разрешения?
(Я видел другие подобные вопросы, опубликованные об ошибках отказа в разрешении Firestore, но в этих случаях правила более конкретны. В настоящее время этот проект даже не требует авторизации для доступа к Firestore.)
1 ответ
Я столкнулся с этой же проблемой, но мне удалось ее исправить. Настройте учетную запись службы и укажите на это свой экземпляр Firestore. Вы можете создать ключ учетной записи службы здесь. Вот пример блока кода, показывающий, как использовать учетную запись службы. SERVICE_ACCOUNT_PATH - строка, содержащая путь к учетной записи службы, а PROJECT_ID - строка, содержащая идентификатор вашего проекта.
private static void authenticate() throws Exception {
FirestoreOptions firestoreOptions = FirestoreOptions.newBuilder()
.setCredentials(ServiceAccountCredentials.fromStream(new FileInputStream(SERVICE_ACCOUNT_PATH)))
.setProjectId(PROJECT_ID).build();
database = firestoreOptions.getService();
}