Ir para o console

Chamar funções a partir do seu aplicativo

Com os SDKs do cliente do Cloud Functions para Firebase, você pode chamar funções diretamente de um app do Firebase. Para fazer isso, escreva e implante uma função HTTPS chamável no Cloud Functions e adicione a lógica do cliente para chamar a função do seu app.

As funções chamáveis são semelhantes a outras funções HTTP, com os seguintes recursos adicionais:

  • Com as funções chamáveis, os tokens do Firebase Authentication e do FCM são incluídos automaticamente nas solicitações quando estiverem disponíveis.
  • O acionador functions.https.onCall desserializa automaticamente o corpo da solicitação e valida os tokens de autenticação.

O SDK do Firebase para Cloud Functions v0.9.1 e versões posteriores opera com essas versões mínimas do SDK do cliente do Firebase para oferecer compatibilidade com funções HTTPS chamáveis:

  • SDK do Firebase para iOS 5.18.2
  • SDK do Firebase para Android 16.3.0
  • SDK do Firebase para JavaScript 5.9.0

Se você quer adicionar um recurso semelhante a um aplicativo integrado em uma plataforma sem suporte, consulte Especificação do protocolo para https.onCall. Você verá instruções na outra parte deste guia sobre como escrever, implantar e chamar uma função HTTPS chamável para iOS, Android, Web, C ++ e Unity.

Como escrever e implantar a função chamável

Use functions.https.onCall para criar uma função HTTPS chamável. Esse método tem dois parâmetros: data e context opcional:

// Saves a message to the Firebase Realtime Database but sanitizes the text by removing swearwords.
exports.addMessage = functions.https.onCall((data, context) => {
  // ...
});

Para uma função chamável que salva uma mensagem de texto para o Realtime Database, por exemplo, data pode conter o texto da mensagem, enquanto os parâmetros context representam a informação de autenticação do usuário:

// Message text passed from the client.
const text = data.text;// Authentication / user information is automatically added to the request.
const uid = context.auth.uid;
const name = context.auth.token.name || null;
const picture = context.auth.token.picture || null;
const email = context.auth.token.email || null;

A distância entre o local da função chamável e o do cliente que faz o chamado pode criar uma latência de rede significativa. Para otimizar o desempenho, especifique o local da função, quando aplicável, e alinhe o local da função chamável ao local definido ao inicializar o SDK no cliente.

Como enviar o resultado de volta

Para enviar dados de volta para o cliente, retorne dados que podem ser codificados com JSON. Por exemplo, para retornar o resultado de uma operação de adição:

// returning result.
return {
  firstNumber: firstNumber,
  secondNumber: secondNumber,
  operator: '+',
  operationResult: firstNumber + secondNumber,
};

Para retornar dados após uma operação assíncrona, retorne uma promessa. Os dados retornados pela promessa são enviados de volta ao cliente. Por exemplo, você pode retornar o texto limpo que a função chamável escreveu no Realtime Database:

// Saving the new message to the Realtime Database.
const sanitizedMessage = sanitizer.sanitizeText(text); // Sanitize the message.
return admin.database().ref('/messages').push({
  text: sanitizedMessage,
  author: { uid, name, picture, email },
}).then(() => {
  console.log('New Message written');
  // Returning the sanitized message to the client.
  return { text: sanitizedMessage };
})

Como solucionar erros

Para garantir que o cliente receba detalhes de erro úteis, retorne erros de uma função chamável ao emitir uma instância functions.https.HttpsError ou retornar uma promessa recusada com essa instância. O erro tem um atributo code que pode ser um dos valores listados em functions.https..HttpsError Os erros também têm uma string message, que tem como padrão uma string vazia. Eles também podem ter um campo details opcional com um valor arbitrário. Se um erro diferente de HttpsError for emitido pelas suas funções, seu cliente receberá um erro com a mensagem INTERNAL e o código internal.

Por exemplo, uma função pode emitir erros de validação de dados e autenticação com mensagens de erro para retornar ao cliente que faz o chamado:

// Checking attribute.
if (!(typeof text === 'string') || text.length === 0) {
  // Throwing an HttpsError so that the client gets the error details.
  throw new functions.https.HttpsError('invalid-argument', 'The function must be called with ' +
      'one arguments "text" containing the message text to add.');
}
// Checking that the user is authenticated.
if (!context.auth) {
  // Throwing an HttpsError so that the client gets the error details.
  throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
      'while authenticated.');
}

Como implantar a função chamável

Depois que você salva uma função chamável completa dentro do index.js, ela é implantada com todas as outras funções quando você executa firebase deploy. Para implantar somente a função chamável, use o argumento --only conforme mostrado para executar implantações parciais:

$ firebase deploy --only functions:addMessage

Como configurar seu ambiente de desenvolvimento de cliente

Verifique se você cumpre todos os pré-requisitos e adicione as dependências e bibliotecas de clientes necessárias ao seu app.

iOS

  1. Siga as instruções para adicionar o Firebase ao seu app para iOS.
  2. Adicione os pods do Cloud Functions ao seu Podfile.
    pod 'Firebase/Core'
    pod 'Firebase/Functions'
  3. Salve o arquivo e execute pod install.

Web

  1. Siga as instruções para adicionar o Firebase ao seu app da Web.
  2. Adicione as bibliotecas do Firebase e do Cloud Functions ao seu app:
    <script src="https://www.gstatic.com/firebasejs/5.9.0/firebase.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.9.0/firebase-functions.js"></script>
    
    O Cloud Functions SDK também está disponível como um pacote npm.
    npm install firebase@5.8.4 --save
    
    Você precisará requisitar manualmente o Firebase e o Cloud Functions.
    const firebase = require("firebase");
    // Required for side-effects
    require("firebase/functions");
    

Android

  1. Siga as instruções para adicionar o Firebase ao seu app para Android.
  2. Adicione a biblioteca Cloud Functions Android ao seu arquivo app/build.gradle:
    implementation 'com.google.firebase:firebase-functions:16.3.0'

C++

Para C ++ com Android:

  1. Siga as instruções para adicionar o Firebase ao seu projeto do C++.
  2. Adicione a biblioteca Cloud Functions Android ao seu arquivo app/build.gradle:
    implementation 'com.google.firebase:firebase-functions:16.3.0'
  3. Vincule as bibliotecas estáticas libfirebase_app.a e libfirebase_functions.a por meio do SDK para C++.

Para o C ++ com iOS:

  1. Siga as instruções para adicionar o Firebase ao seu projeto do C++.
  2. Adicione os pods do Cloud Functions ao seu Podfile.
    pod 'Firebase/Core'
    pod 'Firebase/Functions'
  3. Salve o arquivo e execute pod install.
  4. Adicione firebase.framework e firebase_functions.framework ao seu projeto do Xcode por meio do SDK para C++.

Unity

  1. Faça o download do SDK para Unity do Firebase.
  2. Siga as instruções para adicionar o Firebase ao seu projeto do Unity.
  3. Selecione o item de menu Recursos > Importar pacote > Pacote personalizado.
  4. Importe o pacote FirebaseFunctions.unitypackage do SDK do Firebase para Unity salvo anteriormente.
  5. Quando a janela Importar pacote do Unity for exibida, clique no botão Importar.

Como inicializar o SDK do cliente

Inicialize uma instância do Cloud Functions:

Swift

lazy var functions = Functions.functions()

Objective-C

@property(strong, nonatomic) FIRFunctions *functions;// ...
self.functions = [FIRFunctions functions];

Web

firebase.initializeApp({
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
  projectId: '### CLOUD FUNCTIONS PROJECT ID ###'
  databaseURL: 'https://### YOUR DATABASE NAME ###.firebaseio.com',
});

// Initialize Cloud Functions through Firebase
var functions = firebase.functions();

Java
Android

private FirebaseFunctions mFunctions;// ...
mFunctions = FirebaseFunctions.getInstance();

Kotlin
Android

private lateinit var functions: FirebaseFunctions// ...
functions = FirebaseFunctions.getInstance()

C++

firebase::functions::Functions* functions;
// ...
functions = firebase::functions::Functions::GetInstance(app);

Unity

functions = Firebase.Functions.DefaultInstance;

Como chamar a função

Swift

functions.httpsCallable("addMessage").call(["text": inputField.text]) { (result, error) in
  if let error = error as NSError? {
    if error.domain == FunctionsErrorDomain {
      let code = FunctionsErrorCode(rawValue: error.code)
      let message = error.localizedDescription
      let details = error.userInfo[FunctionsErrorDetailsKey]
    }
    // ...
  }
  if let text = (result?.data as? [String: Any])?["text"] as? String {
    self.resultField.text = text
  }
}

Objective-C

[[_functions HTTPSCallableWithName:@"addMessage"] callWithObject:@{@"text": _inputField.text}
                                                      completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) {
  if (error) {
    if (error.domain == FIRFunctionsErrorDomain) {
      FIRFunctionsErrorCode code = error.code;
      NSString *message = error.localizedDescription;
      NSObject *details = error.userInfo[FIRFunctionsErrorDetailsKey];
    }
    // ...
  }
  self->_resultField.text = result.data[@"text"];
}];

Web

var addMessage = firebase.functions().httpsCallable('addMessage');
addMessage({text: messageText}).then(function(result) {
  // Read result of the Cloud Function.
  var sanitizedMessage = result.data.text;
  // ...
});

Java
Android

private Task<String> addMessage(String text) {
    // Create the arguments to the callable function.
    Map<String, Object> data = new HashMap<>();
    data.put("text", text);
    data.put("push", true);

    return mFunctions
            .getHttpsCallable("addMessage")
            .call(data)
            .continueWith(new Continuation<HttpsCallableResult, String>() {
                @Override
                public String then(@NonNull Task<HttpsCallableResult> task) throws Exception {
                    // This continuation runs on either success or failure, but if the task
                    // has failed then getResult() will throw an Exception which will be
                    // propagated down.
                    String result = (String) task.getResult().getData();
                    return result;
                }
            });
}

Kotlin
Android

private fun addMessage(text: String): Task<String> {
    // Create the arguments to the callable function.
    val data = hashMapOf(
        "text" to text,
        "push" to true
    )

    return functions
            .getHttpsCallable("addMessage")
            .call(data)
            .continueWith { task ->
                // This continuation runs on either success or failure, but if the task
                // has failed then result will throw an Exception which will be
                // propagated down.
                val result = task.result?.data as String
                result
            }
}

C++

firebase::Future<firebase::functions::HttpsCallableResult> AddMessage(
    const string& text) {
  // Create the arguments to the callable function.
  firebase::Variant data = firebase::Variant::EmptyMap();
  data.map()["text"] = firebase::Variant(text);
  data.map()["push"] = true;

  // Call the function and add a callback for the result.
  firebase::functions::HttpsCallableReference doSomething =
      functions->GetHttpsCallable("addMessage");
  return doSomething.Call(data);
}

Unity

private Task<string> addMessage(string text) {
  // Create the arguments to the callable function.
  var data = new Dictionary<string, object>();
  data["text"] = text;
  data["push"] = true;

  // Call the function and extract the operation from the result.
  var function = functions.GetHttpsCallable("addMessage");
  return function.CallAsync(data).ContinueWith((task) => {
    return (string) task.Result.Data;
  });
}

Como solucionar erros no cliente

O cliente receberá um erro se o servidor emitir um erro ou se a promessa resultante for recusada.

Se o erro retornado pela função for do tipo function.https.HttpsError, o cliente receberá code, message e details do erro do servidor. Caso contrário, o erro conterá a mensagem INTERNAL e o código INTERNAL. Consulte as orientações sobre como solucionar erros na sua função chamável.

Swift

if let error = error as NSError? {
  if error.domain == FunctionsErrorDomain {
    let code = FunctionsErrorCode(rawValue: error.code)
    let message = error.localizedDescription
    let details = error.userInfo[FunctionsErrorDetailsKey]
  }
  // ...
}

Objective-C

if (error) {
  if (error.domain == FIRFunctionsErrorDomain) {
    FIRFunctionsErrorCode code = error.code;
    NSString *message = error.localizedDescription;
    NSObject *details = error.userInfo[FIRFunctionsErrorDetailsKey];
  }
  // ...
}

Web

var addMessage = firebase.functions().httpsCallable('addMessage');
addMessage({text: messageText}).then(function(result) {
  // Read result of the Cloud Function.
  var sanitizedMessage = result.data.text;}).catch(function(error) {
  // Getting the Error details.
  var code = error.code;
  var message = error.message;
  var details = error.details;
  // ...
});

Java
Android

addMessage(inputMessage)
        .addOnCompleteListener(new OnCompleteListener<String>() {
            @Override
            public void onComplete(@NonNull Task<String> task) {
                if (!task.isSuccessful()) {
                    Exception e = task.getException();
                    if (e instanceof FirebaseFunctionsException) {
                        FirebaseFunctionsException ffe = (FirebaseFunctionsException) e;
                        FirebaseFunctionsException.Code code = ffe.getCode();
                        Object details = ffe.getDetails();
                    }

                    // ...
                }

                // ...
            }
        });

Kotlin
Android

addMessage(inputMessage)
        .addOnCompleteListener(OnCompleteListener { task ->
            if (!task.isSuccessful) {
                val e = task.exception
                if (e is FirebaseFunctionsException) {
                    val code = e.code
                    val details = e.details
                }

                // ...
            }

            // ...
        })

C++

void OnAddMessageCallback(
    const firebase::Future<firebase::functions::HttpsCallableResult>& future) {
  if (future.error() != firebase::functions::kErrorNone) {
    // Function error code, will be kErrorInternal if the failure was not
    // handled properly in the function call.
    auto code = static_cast<firebase::functions::Error>(future.error());

    // Display the error in the UI.
    DisplayError(code, future.error_message());
    return;
  }

  const firebase::functions::HttpsCallableResult *result = future.result();
  firebase::Variant data = result->data();
  // This will assert if the result returned from the function wasn't a string.
  string message = data.string_value();
  // Display the result in the UI.
  DisplayResult(message);
}

// ...

// ...
  auto future = AddMessage(message);
  future.OnCompletion(OnAddMessageCallback);
// ...

Unity

 addMessage(text).ContinueWith((task) => {
  if (task.IsFaulted) {
    foreach (var inner in task.Exception.InnerExceptions) {
      if (inner is FunctionsException) {
        var e = (FunctionsException) inner;
        // Function error code, will be INTERNAL if the failure
        // was not handled properly in the function call.
        var code = e.ErrorCode;
        var message = e.ErrorMessage;
      }
    }
  } else {
    string result = task.Result;
  }
});