Как удалить коллекцию Firestore с Android - PullRequest
0 голосов
/ 03 сентября 2018

Выпуск

Я ищу временное решение для удаления Коллекций со стороны клиента для моего подтверждения концепции. В конечном итоге я перенесу это на сервер в соответствии с рекомендациями.

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

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Чтобы удалить всю коллекцию или вложенную коллекцию из базы данных Cloud Firestore, вам нужно извлечь все документы в коллекции или вложенной коллекции и удалить их.

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

Даже если команда удаления не рекомендует команду Firebase, поскольку она имеет негативные последствия для безопасности и производительности, вы все равно можете сделать это, но только для small collections. Если вам нужно удалить целые коллекции для Интернета, делайте это только из среды доверенного сервера.

Для Kotlin, пожалуйста, используйте следующие функции:

private fun deleteCollection(collection: CollectionReference, executor: Executor) {
    Tasks.call(executor) {
        val batchSize = 10
        var query = collection.orderBy(FieldPath.documentId()).limit(batchSize.toLong())
        var deleted = deleteQueryBatch(query)

        while (deleted.size >= batchSize) {
            val last = deleted[deleted.size - 1]
            query = collection.orderBy(FieldPath.documentId()).startAfter(last.id).limit(batchSize.toLong())

            deleted = deleteQueryBatch(query)
        }

        null
    }
}

@WorkerThread
@Throws(Exception::class)
private fun deleteQueryBatch(query: Query): List<DocumentSnapshot> {
    val querySnapshot = Tasks.await(query.get())

    val batch = query.firestore.batch()
    for (snapshot in querySnapshot) {
        batch.delete(snapshot.reference)
    }
    Tasks.await(batch.commit())

    return querySnapshot.documents
}
0 голосов
/ 03 сентября 2018

Обновленное решение

Документированное решение команды Firebase Удалить коллекции и подколлекции является более надежным и безопасным, поскольку оно реализовано в облачной функции за пределами клиента. Я соответственно изменил свое решение.

/**
* Initiate a recursive delete of documents at a given path.
*
* This delete is NOT an atomic operation and it's possible
* that it may fail after only deleting some documents.
*
* @param {string} data.path the document or collection path to delete.
*/

exports.deleteUser = () => functions.runWith({timeoutSeconds: 540, memory: '2GB'})
   .https.onCall((data, context) => {
    if (context.auth.uid !== data.userId)
      throw new functions.https.HttpsError(
        'permission-denied','Must be an administrative user to initiate delete.');
    const path = data.path;
    console.log(`User ${context.auth.uid} has requested to delete path ${path}`);

    return firebase_tools.firestore.delete(path, {
      project: process.env.GCLOUD_PROJECT,
      recursive: true,
      yes: true,
      token: functions.config().fb.token
    }).then(() => { return { path: path }; });
});

Старое решение (выполняется на стороне клиента)

В метод передается ссылка на коллекцию пользователя и размер пакета для обработки.

fun deleteCollection(collection: CollectionReference, batchSize: Int) {
    try {
        // Retrieve a small batch of documents to avoid out-of-memory errors/
        var deleted = 0
        collection
                .limit(batchSize.toLong())
                .get()
                .addOnCompleteListener {
                    for (document in it.result.documents) {
                        document.getReference().delete()
                        ++deleted
                    }
                    if (deleted >= batchSize) {
                        // retrieve and delete another batch
                        deleteCollection(collection, batchSize)
                    }
                }
    } catch (e: Exception) {
        System.err.println("Error deleting collection : " + e.message)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...