Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Excluir dados com um Cloud Function que pode ser chamado

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

A página descreve como usar um Cloud Function que pode ser chamado para excluir dados. Depois de implantar essa função, você pode chamá-la diretamente de seu aplicativo móvel ou site para excluir recursivamente documentos e coleções. Por exemplo, você pode usar essa solução para fornecer a usuários selecionados a capacidade de excluir coleções inteiras.

Para outras maneiras de excluir coleções, consulte Excluir dados .

Solução: exclua dados com um Cloud Function que pode ser chamado

A exclusão de coleções inteiras de um aplicativo móvel com recursos limitados pode ser difícil de implementar pelos seguintes motivos:

  • Não há operação que exclua atomicamente uma coleção.
  • A exclusão de um documento não exclui os documentos em suas subcoleções.
  • Se seus documentos tiverem subcoleções dinâmicas, pode ser difícil saber quais dados excluir para um determinado caminho.
  • A exclusão de uma coleção de mais de 500 documentos requer várias operações de gravação em lote ou centenas de exclusões únicas.
  • Em muitos aplicativos, não é apropriado dar permissão aos usuários finais para excluir coleções inteiras.

Felizmente, você pode escrever uma Função do Cloud que pode ser chamada para executar exclusões seguras e eficientes de coleções inteiras ou árvores de coleções. A Função do Cloud abaixo implementa uma função que pode ser chamada, o que significa que ela pode ser chamada diretamente do seu aplicativo ou site para dispositivos móveis, como faria para uma função local.

Para implantar a função e experimentar uma demonstração, consulte o código de exemplo.

Função de nuvem

A Função do Cloud abaixo exclui uma coleção e todos os seus descendentes.

Em vez de implementar sua própria lógica de exclusão recursiva para o Cloud Function, você pode aproveitar o comando firestore:delete na interface de linha de comando (CLI) do Firebase. Você pode importar qualquer função da Firebase CLI para seu aplicativo Node.js usando o pacote firebase-tools .

A Firebase CLI usa a API REST do Cloud Firestore para encontrar todos os documentos no caminho especificado e excluí-los individualmente. Essa implementação não requer conhecimento da hierarquia de dados específica do seu aplicativo e até localizará e excluirá documentos "órfãos" que não têm mais um pai.

Node.js

/**
 * Initiate a recursive delete of documents at a given path.
 * 
 * The calling user must be authenticated and have the custom "admin" attribute
 * set to true on the auth token.
 * 
 * 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.recursiveDelete = functions
  .runWith({
    timeoutSeconds: 540,
    memory: '2GB'
  })
  .https.onCall(async (data, context) => {
    // Only allow admin users to execute this function.
    if (!(context.auth && context.auth.token && context.auth.token.admin)) {
      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}`
    );

    // Run a recursive delete on the given document or collection path.
    // The 'token' must be set in the functions config, and can be generated
    // at the command line by running 'firebase login:ci'.
    await firebase_tools.firestore
      .delete(path, {
        project: process.env.GCLOUD_PROJECT,
        recursive: true,
        force: true,
        token: functions.config().fb.token
      });

    return {
      path: path 
    };
  });

Invocação do cliente

Para chamar a função, obtenha uma referência à função do SDK do Firebase e transmita os parâmetros necessários:

Rede
/**
 * Call the 'recursiveDelete' callable function with a path to initiate
 * a server-side delete.
 */
function deleteAtPath(path) {
    var deleteFn = firebase.functions().httpsCallable('recursiveDelete');
    deleteFn({ path: path })
        .then(function(result) {
            logMessage('Delete success: ' + JSON.stringify(result));
        })
        .catch(function(err) {
            logMessage('Delete failed, see console,');
            console.warn(err);
        });
}
Rápido
Observação: este produto não está disponível em destinos watchOS e App Clip.
    // Snippet not yet written
    
Objetivo-C
Observação: este produto não está disponível em destinos watchOS e App Clip.
    // Snippet not yet written
    

Java

/**
 * Call the 'recursiveDelete' callable function with a path to initiate
 * a server-side delete.
 */
public void deleteAtPath(String path) {
    Map<String, Object> data = new HashMap<>();
    data.put("path", path);

    HttpsCallableReference deleteFn =
            FirebaseFunctions.getInstance().getHttpsCallable("recursiveDelete");
    deleteFn.call(data)
            .addOnSuccessListener(new OnSuccessListener<HttpsCallableResult>() {
                @Override
                public void onSuccess(HttpsCallableResult httpsCallableResult) {
                    // Delete Success
                    // ...
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    // Delete failed
                    // ...
                }
            });
}

Kotlin+KTX

/**
 * Call the 'recursiveDelete' callable function with a path to initiate
 * a server-side delete.
 */
fun deleteAtPath(path: String) {
    val deleteFn = Firebase.functions.getHttpsCallable("recursiveDelete")
    deleteFn.call(hashMapOf("path" to path))
            .addOnSuccessListener {
                // Delete Success
                // ...
            }
            .addOnFailureListener {
                // Delete Failed
                // ...
            }
}

Ao usar o SDK do cliente para funções de nuvem que podem ser chamadas, o estado de autenticação dos usuários e o parâmetro de path são transmitidos perfeitamente para a função remota. Quando a função for concluída, o cliente receberá um retorno de chamada com o resultado ou uma exceção. Para saber como chamar uma função de nuvem do Android, Apple ou outra plataforma, leia a documentação .

Limitações

A solução mostrada acima demonstra a exclusão de coleções de uma função que pode ser chamada, mas você deve estar ciente das seguintes limitações:

  • Consistência - o código acima exclui os documentos um de cada vez. Se você consultar enquanto há uma operação de exclusão em andamento, seus resultados podem refletir um estado parcialmente completo em que apenas alguns documentos direcionados são excluídos. Também não há garantia de que as operações de exclusão terão êxito ou falharão uniformemente, portanto, esteja preparado para lidar com casos de exclusão parcial.
  • Tempos limite - a função acima está configurada para ser executada por um máximo de 540 segundos antes do tempo limite. O código de exclusão pode excluir 4.000 documentos por segundo na melhor das hipóteses. Se você precisar excluir mais de 2.000.000 de documentos, considere executar a operação em seu próprio servidor para que não expire. Para obter um exemplo de como excluir uma coleção de seu próprio servidor, consulte Excluir coleções .