как установить правила проверки, чтобы разрешить создание документов, только если документы с такими же полями отсутствуют в Cloud Firestore - PullRequest
0 голосов
/ 26 мая 2019

Я пытаюсь использовать Cloud Firestore с моим приложением для Android. Так что я храню 3-4 поля. Итак, я приведу пример с коллекцией автомобилей. Есть коллекция "cars". Документы коллекции автомобилей имеют поля: производитель, модель, максимальная скорость.

Я добавляю данные с Android с кодом, как показано ниже:

dManufacturer = "Hyundai"
dModel = "Kona"
dTopSpeed ="150"
Map<String, Object> car = new HashMap<>();
car.put("manufacturer", dManufacturer);
car.put("model", dModel);
car.put("top_speed",dTopSpeed);


db.collection(cars")
.add(car)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
 @Override
 public void onSuccess(DocumentReference documentReference) {
 Log.d("firebaseab", "DocumentSnapshot added with ID: " + documentReference.getId());
 }
})
.addOnFailureListener(new OnFailureListener() {
 @Override
 public void onFailure(@NonNull Exception e) {
 Log.w("firebaseab", "Error adding document", e);
 }
});

Таким образом, любой пользователь, использующий мое приложение, должен иметь возможность добавить только 1 автомобильный документ, и этот документ, если все значения полей аналогичны документу в коллекции, данные не должны добавляться.

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

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

способы, которые я попробовал:

1) Я пытался написать правило для совпадения "! =" С документами в коллекции к тому, что я делал в запросе на создание, который я делаю с Android, как указано выше, но это давало мне ошибки. я еще не совсем понял, что происходит. правило как:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read;
    }
    // match /{document=**} {
    //   //allow create: if document != request.resource.data;
    //   allow create: if document.manufacturer == "Google";
    // }
    match /cars/{car} {
      allow create : if request.resource.data.manufacturer != resource.data.manufacturer
                    && request.resource.data.model != resource.data.model
                    && request.resource.data.topSpeed != resource.data.topSpeed;

    }
  }
}

Но вышесказанное дало ошибку и не работало.

Не знаю, как использовать! Существующие для сравнения в документе с теми же значениями полей, существует или нет. Они могут иметь разные идентификаторы документов, но если значения полей совпадают, я не хочу добавлять другой документ с такими же значениями полей.

Пути, о которых я думаю, но не знаю, что правильно и как их реализовать:

1) Будет ли создание составного индекса со всеми значениями, которым я должен соответствовать там? Но как мне написать правила безопасности, чтобы мне не приходилось проверять или выполнять запросы на получение из моего кода.

2) Должен ли я создать идентификатор документа в качестве индекса компоновки (но как мне это сделать и как написать правила проверки безопасности)

3) Должен ли я создать идентификатор документа со стороны клиента в формате "factory_model_topspeed". Так было бы по моему примеру - "Hyundai_Kona_150". Поможет ли это сохранить уникальность? Если это произойдет, то при вводе документа с таким же идентификатором документа в разрешении будет отказано. Тогда как я должен справиться с этим на клиенте. Могу ли я отправить конкретное сообщение или значение из облачного пожарного магазина, описывающее это конкретное событие, запрещающее создание?

4) Должен ли я использовать Device.Id в Android в качестве идентификатора документа для сопоставления с конкретным устройством, поэтому, если пользователь добавил документ, он не может добавить больше. Но это может создать дублирование данных поля документа. Я спрашиваю это о том, как написать правила безопасности, чтобы человек, который уже написал документ, не мог написать снова.

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

Есть ли другой лучший способ решения этой проблемы ... пожалуйста, скажите. Я могу даже использовать немного кода на стороне клиента, чтобы использовать выражение where и т. Д., Но я хочу минимизировать квоту чтения. Как это сделать с минимальной квотой чтения / записи. Я начинающий с облачного пожарного магазина.

1 Ответ

0 голосов
/ 26 мая 2019

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

Что правила безопасности может сделать, это проверить значения определенного документа или наличие определенного документа. В обоих случаях вы должны знать полный путь к документу, включая идентификатор соответствующего документа.

Итак, вы можете создать дополнительную коллекцию, в которой ключ / идентификатор каждого документа представляет собой объединение всех значений полей, которые вы хотите быть уникальными. Тогда ваши правила безопасности могут проверить, существует ли уже документ в этой вторичной коллекции (часто называемый «индекс»), и запретить запись, если это так.

Кроме того, вы можете создать облачную функцию, которая выполняет создание документов. В своем коде облачных функций вы можете запросить базу данных, и только создать документ без конфликта существует. Когда вы используете этот подход, вы все равно можете позволить приложению напрямую читать из базы данных и выполнять обновления.

...