Call functions from your app

The Cloud Functions for Firebase client SDKs let you call functions directly from a Firebase app. To call a function from your app in this way, write and deploy an HTTPS Callable function in Cloud Functions, and then add client logic to call the function from your app.

Callable functions are similar to other HTTP functions, with these additional features:

  • With callables, Firebase Authentication and FCM tokens, when available, are automatically included in requests.
  • The functions.https.onCall trigger automatically deserializes the request body and validates auth tokens.

The Firebase SDK for Cloud Functions v0.9.1 and higher interoperates with these Firebase client SDK minimum versions to support HTTPS Callable functions:

  • Firebase SDK for iOS 5.8.0
  • Firebase SDK for Android 16.1.0
  • Firebase JavaScript SDK 5.5.0

If you want to add similar functionality to an app built on an unsupported platform, see the Protocol Specification for https.onCall. The rest of this guide provides instructions on how to write, deploy, and call an HTTPS callable function for iOS, Android, web, C++ and Unity.

Write and deploy the callable function

Use functions.https.onCall to create an HTTPS callable function. This method takes two parameters: data, and optional context:

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

For a callable function that saves a text message to the Realtime Database, for example, data could contain the message text, while context parameters represent user auth information:

// 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;

Distance between the location of the callable function and the location of the calling client can create network latency. To optimize performance, consider specifying the function location where applicable, and make sure to align the callable's location with the location set when you initialize the SDK on the client side.

Sending back the result

To send data back to the client, return data that can be JSON encoded. For example, to return the result of an addition operation:

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

To return data after an asynchronous operation, return a promise. The data returned by the promise is sent back to the client. For example, you could return sanitized text that the callable function wrote to the 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 };
})

Handle errors

To ensure the client gets useful error details, return errors from a callable by throwing (or returning a Promise rejected with) an instance of functions.https.HttpsError. The error has a code attribute that can be one of the values listed at functions.https.HttpsError. The errors also have a string message, which defaults to an empty string. They can also have an optional details field with an arbitrary value. If an error other than HttpsError is thrown from your functions, your client instead receives an error with the message INTERNAL and the code internal.

For example, a function could throw data validation and authentication errors with error messages to return to the calling client:

// 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.');
}

Deploy the callable function

After you save a completed callable function within index.js, it is deployed along with all other functions when you run firebase deploy. To deploy only the callable, use the --only argument as shown to perform partial deploys:

$ firebase deploy --only functions:addMessage

Set up your client development environment

Make sure you meet any prerequisites, and add the required dependencies and client libraries to your app.

iOS

  1. Follow the instructions to add Firebase to your iOS app.
  2. Add the Cloud Functions pods to your Podfile
    pod 'Firebase/Core'
    pod 'Firebase/Functions'
  3. Save the file and run pod install.

Web

  1. Follow the instructions to add Firebase to your Web app.
  2. Add the Firebase and Cloud Functions client libraries to your app:
    <script src="https://www.gstatic.com/firebasejs/5.5.0/firebase.js"></script>
    <script src="https://www.gstatic.com/firebasejs/5.5.0/firebase-functions.js"></script>
    
    The Cloud Functions SDK is also available as an npm package.
    npm install firebase@5.3.0 --save
    
    You'll need to manually require both Firebase and Cloud Functions.
    const firebase = require("firebase");
    // Required for side-effects
    require("firebase/functions");
    

Android

  1. Follow the instructions to add Firebase to your Android app.
  2. Add the Cloud Functions Android library to your app/build.gradle file:
    implementation 'com.google.firebase:firebase-functions:16.1.0'

C++

For C++ with Android:

  1. Follow the instructions to add Firebase to your C++ project.
  2. Add the Cloud Functions Android library to your app/build.gradle file:
    implementation 'com.google.firebase:firebase-functions:16.1.0'
  3. Link the libfirebase_app.a and libfirebase_functions.a static library from the C++ SDK.

For C++ with iOS:

  1. Follow the instructions to add Firebase to your C++ project.
  2. Add the Cloud Functions pods to your Podfile
    pod 'Firebase/Core'
    pod 'Firebase/Functions'
  3. Save the file and run pod install.
  4. Add firebase.framework and firebase_functions.framework from the C++ SDK to your Xcode project.

Unity

  1. Download the Firebase Unity SDK.
  2. Follow the instructions to add Firebase to your Unity project.
  3. Select the Assets > Import Package > Custom Package menu item.
  4. Import the FirebaseFunctions.unitypackage package from the Firebase Unity SDK, downloaded previously.
  5. When the Import Unity Package window appears, click the Import button.

Initialize the client SDK

Initialize an instance of 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();

Android

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

C++

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

Unity

functions = Firebase.Functions.DefaultInstance;

Call the function

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;
  // ...
});

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;
                }
            });
}

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;
  });
}

Handle errors on the client

The client receives an error if the server threw an error or if the resulting promise was rejected.

If the error returned by the function is of type function.https.HttpsError, then the client receives the error code, message, and details from the server error. Otherwise, the error contains the message INTERNAL and the code INTERNAL. See guidance for how to handle errors in your callable function.

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;
  // ...
});

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();
                    }

                    // ...
                }

                // ...
            }
        });

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;
  }
});

Оставить отзыв о...

Текущей странице
Нужна помощь? Обратитесь в службу поддержки.