Catch up on everthing we announced at this year's Firebase Summit. Learn more

Funkcje połączeń z Twojej aplikacji

Pakiety SDK klienta Cloud Functions dla Firebase umożliwiają wywoływanie funkcji bezpośrednio z aplikacji Firebase. Aby wywołać funkcję z aplikacji w ten sposób, napisz i wdróż funkcję wywoływaną HTTPS w Cloud Functions, a następnie dodaj logikę klienta, aby wywołać funkcję z aplikacji.

Ważne jest, aby pamiętać, że HTTPS wywoływalne funkcje są podobne, ale nie identyczne funkcje HTTP. Aby skorzystać z funkcji HTTPS wywołalnych należy użyć klienta SDK dla platformy wraz z functions.https backend API (lub wdrożenia protokołu). Wywoływalne mają te kluczowe różnice w stosunku do funkcji HTTP:

  • Dzięki wywoływalności tokeny uwierzytelniania Firebase, tokeny FCM i tokeny sprawdzania aplikacji, jeśli są dostępne, są automatycznie dołączane do żądań.
  • functions.https.onCall spust automatycznie deserializes ciało zapytanie i sprawdza auth tokenów.

Pakiet Firebase SDK dla Cloud Functions w wersji 0.9.1 lub nowszej współpracuje z następującymi minimalnymi wersjami pakietu SDK klienta Firebase, aby obsługiwać funkcje wywoływane HTTPS:

  • Firebase SDK dla platform Apple 8.9.1
  • Pakiet Firebase SDK dla Androida 20.0.1
  • Pakiet Firebase JavaScript SDK 8.10.0
  • Firebase Modular Web SDK w wersji 9.0

Jeśli chcesz dodać podobną funkcjonalność do aplikacji zbudowanej na nieobsługiwanym platformy, zobacz Specyfikacja protokołu dla https.onCall . Pozostała część tego przewodnika zawiera instrukcje dotyczące pisania, wdrażania i wywoływania funkcji wywoływanej HTTPS na platformach Apple, Android, sieci Web, C++ i Unity.

Napisz i wdróż funkcję wywoływalną

Zastosowanie functions.https.onCall stworzyć HTTPS wpłacone funkcji. Metoda ta przyjmuje dwa parametry: data oraz opcjonalnej context :

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

Na żądanie w funkcji, która zapisuje wiadomości tekstowych do bazy danych w czasie rzeczywistym, na przykład, data mogą zawierać tekst wiadomości, a context parametry przedstawiają informacje uwierzytelniania użytkownika:

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

Odległość między lokalizacją funkcji wywoływanej a lokalizacją klienta wywołującego może powodować opóźnienia w sieci. Do wykonywania optymalizacji rozważyć określając lokalizację funkcji w stosownych przypadkach, i upewnij się, aby wyrównać położenia płatnych na żądanie za pomocą zestawu lokalizacji podczas inicjalizacji SDK po stronie klienta.

Opcjonalnie możesz dołączyć zaświadczenie App Check, aby chronić zasoby zaplecza przed nadużyciami, takimi jak oszustwa związane z rozliczeniami lub wyłudzanie informacji. Zobacz Włącz App Sprawdź egzekwowania dla funkcji chmurze .

Odesłanie wyniku

Aby wysłać dane z powrotem do klienta, zwróć dane, które mogą być zakodowane w formacie JSON. Na przykład, aby zwrócić wynik operacji dodawania:

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

Aby zwrócić dane po operacji asynchronicznej, zwróć obietnicę. Dane zwrócone przez promesę są odsyłane do klienta. Na przykład możesz zwrócić oczyszczony tekst, który wywoływalna funkcja zapisała do Bazy danych czasu rzeczywistego:

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

Obsługa błędów

Aby upewnić się, że klient dostaje użyteczne dane o błędach, błędy powrocie z wpłacone przez rzucanie (lub powrocie z Promise odrzucone) wystąpienie functions.https.HttpsError . Błąd ma code atrybutu, który może być jedną z wartości wymienionych w functions.https.HttpsError . Błędy mają także ciąg message , która domyślnie jest pusty ciąg. Mogą również mieć opcjonalny details pole z dowolnej wartości. Jeśli inny błąd niż HttpsError zostaje wyrzucony ze swoich funkcji, klient zamiast odbiera błąd z komunikatem INTERNAL i kodu internal .

Na przykład funkcja może zgłaszać błędy walidacji i uwierzytelniania danych z komunikatami o błędach, aby powrócić do klienta wywołującego:

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

Wdróż funkcję wywoływalną

Po zapisaniu wypełniony wpłacone funkcji w index.js , jest wdrożony wraz ze wszystkimi innymi funkcjami Po uruchomieniu firebase deploy . Aby wdrożyć tylko wywoływalny użyj --only argumentu jak pokazano przeprowadzić częściowe rozmieszcza :

$ firebase deploy --only functions:addMessage

W przypadku napotkania błędów z uprawnieniami podczas wdrażania funkcji, upewnij się, że odpowiednie role IAM są przypisane do użytkownika z systemem poleceń wdrażania.

Skonfiguruj środowisko programistyczne klienta

Upewnij się, że spełniasz wszystkie wymagania wstępne, a następnie dodaj wymagane zależności i biblioteki klienta do swojej aplikacji.

iOS+

Postępuj zgodnie z instrukcjami, aby dodać Firebase do aplikacji firmy Apple .

Użyj Menedżera pakietów Swift, aby zainstalować zależności Firebase i zarządzać nimi.

  1. W Xcode, z projektem otwartej aplikacji, należy przejść do menu Plik> Swift Pakiety> Dodaj Package zależność.
  2. Po wyświetleniu monitu dodaj repozytorium SDK platformy Firebase Apple:
  3.   https://github.com/firebase/firebase-ios-sdk
      
  4. Wybierz bibliotekę Cloud Functions.
  5. Po zakończeniu Xcode automatycznie rozpocznie rozwiązywanie i pobieranie twoich zależności w tle.

Wersja internetowa 9

  1. Postępuj zgodnie z instrukcjami, aby dodać Firebase do aplikacji sieci Web . Upewnij się, uruchom następujące polecenie z terminala:
    npm install firebase@9.5.0 --save
    
  2. Ręcznie wymagaj zarówno rdzenia Firebase, jak i Cloud Functions:

     import { initializeApp } from 'firebase/app';
     import { getFunctions } from 'firebase/functions';
    
     const app = initializeApp({
         projectId: '### CLOUD FUNCTIONS PROJECT ID ###',
         apiKey: '### FIREBASE API KEY ###',
         authDomain: '### FIREBASE AUTH DOMAIN ###',
       });
     const functions = getFunctions(app);
    

Wersja internetowa 8

  1. Postępuj zgodnie z instrukcjami, aby dodać Firebase do aplikacji sieci Web .
  2. Dodaj rdzeń Firebase i chmura Funkcje bibliotek klienckich aplikacji:
    <script src="https://www.gstatic.com/firebasejs/8.10.0/firebase.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-functions.js"></script>
    

Zestaw SDK Cloud Functions jest również dostępny jako pakiet npm.

  1. Uruchom następujące polecenia z terminala:
    npm install firebase@8.10.0 --save
    
  2. Ręcznie wymagają zarówno rdzeń Firebase i funkcje Cloud
    const firebase = require("firebase");
    // Required for side-effects
    require("firebase/functions");
    

Jawa

  1. Postępuj zgodnie z instrukcjami, aby dodać Firebase do aplikacji na Androida .

  2. Korzystanie z Firebase Android Bom , deklarują zależność dla funkcji Chmura Android biblioteki w module (app szczebla) Gradle plik (zazwyczaj app/build.gradle ).

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:29.0.1')
    
        // Declare the dependency for the Cloud Functions library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-functions'
    }
    

    Korzystając z Firebase Bom Android , aplikacja będzie zawsze używać kompatybilne wersje bibliotek Firebase Android.

    (Alternatywna) Stwierdzenie Firebase zależności biblioteki bez użycia BOM

    Jeśli zdecydujesz się nie używać zestawienia komponentów Firebase, musisz określić każdą wersję biblioteki Firebase w jej wierszu zależności.

    Należy pamiętać, że w przypadku korzystania z wielu bibliotek Firebase w swojej aplikacji, zalecamy korzystania z BOM do zarządzania wersjami biblioteki, co gwarantuje, że wszystkie wersje są kompatybilne.

    dependencies {
        // Declare the dependency for the Cloud Functions library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-functions:20.0.1'
    }
    

Kotlin+KTX

  1. Postępuj zgodnie z instrukcjami, aby dodać Firebase do aplikacji na Androida .

  2. Korzystanie z Firebase Android Bom , deklarują zależność dla funkcji Chmura Android biblioteki w module (app szczebla) Gradle plik (zazwyczaj app/build.gradle ).

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:29.0.1')
    
        // Declare the dependency for the Cloud Functions library
        // When using the BoM, you don't specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-functions-ktx'
    }
    

    Korzystając z Firebase Bom Android , aplikacja będzie zawsze używać kompatybilne wersje bibliotek Firebase Android.

    (Alternatywna) Stwierdzenie Firebase zależności biblioteki bez użycia BOM

    Jeśli zdecydujesz się nie używać zestawienia komponentów Firebase, musisz określić każdą wersję biblioteki Firebase w jej wierszu zależności.

    Należy pamiętać, że w przypadku korzystania z wielu bibliotek Firebase w swojej aplikacji, zalecamy korzystania z BOM do zarządzania wersjami biblioteki, co gwarantuje, że wszystkie wersje są kompatybilne.

    dependencies {
        // Declare the dependency for the Cloud Functions library
        // When NOT using the BoM, you must specify versions in Firebase library dependencies
        implementation 'com.google.firebase:firebase-functions-ktx:20.0.1'
    }
    

C++

Dla C ++ z Androidem:

  1. Postępuj zgodnie z instrukcjami, aby dodać Firebase do projektu C ++ .
  2. Dodaj firebase_functions bibliotekę do CMakeLists.txt pliku.

Dla C ++ z platform Apple:

  1. Postępuj zgodnie z instrukcjami, aby dodać Firebase do projektu C ++ .
  2. Dodaj Cloud Funkcje kapsułę do Podfile :
    pod 'Firebase/Functions'
  3. Zapisz plik, a następnie uruchom:
    pod install
  4. Dodaj rdzeń Firebase i chmura Funkcje ram z Firebase C ++ SDK do projektu Xcode.
    • firebase.framework
    • firebase_functions.framework

Jedność

  1. Postępuj zgodnie z instrukcjami, aby dodać Firebase do projektu Unity .
  2. Dodaj FirebaseFunctions.unitypackage z Firebase Unity SDK do projektu Unity.

Zainicjuj klienta SDK

Zainicjuj instancję Cloud Functions:

Szybki

lazy var functions = Functions.functions()

Cel C

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

Wersja internetowa 8

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

Wersja internetowa 9

const app = initializeApp({
  projectId: '### CLOUD FUNCTIONS PROJECT ID ###',
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
});
const functions = getFunctions(app);

Jawa

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

Kotlin+KTX

private lateinit var functions: FirebaseFunctions
// ...
functions = Firebase.functions

C++

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

Jedność

functions = Firebase.Functions.DefaultInstance;

Wywołaj funkcję

Szybki

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 data = result?.data as? [String: Any], let text = data["text"] as? String {
    self.resultField.text = text
  }
}

Cel 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"];
}];

Wersja internetowa 8

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

Wersja internetowa 9

import { getFunctions, httpsCallable } from "firebase/functions";

const functions = getFunctions();
const addMessage = httpsCallable(functions, 'addMessage');
addMessage({ text: messageText })
  .then((result) => {
    // Read result of the Cloud Function.
    /** @type {any} */
    const data = result.data;
    const sanitizedMessage = data.text;
  });

Jawa

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+KTX

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

Jedność

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

Obsługa błędów po stronie klienta

Klient otrzymuje błąd, jeśli serwer zwrócił błąd lub jeśli otrzymana obietnica została odrzucona.

Jeśli błąd zwrócony przez funkcję jest typu function.https.HttpsError , wówczas klient otrzymuje Błąd code , message i details z błędu serwera. W przeciwnym razie błędu zawiera komunikat INTERNAL oraz kod INTERNAL . Zobacz wskazówki dotyczące sposobu obsługi błędów w swojej funkcji na żądanie.

Szybki

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]
  }
  // ...
}

Cel C

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

Wersja internetowa 8

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

Wersja internetowa 9

import { getFunctions, httpsCallable } from "firebase/functions";

const functions = getFunctions();
const addMessage = httpsCallable(functions, 'addMessage');
addMessage({ text: messageText })
  .then((result) => {
    // Read result of the Cloud Function.
    /** @type {any} */
    const data = result.data;
    const sanitizedMessage = data.text;
  })
  .catch((error) => {
    // Getting the Error details.
    const code = error.code;
    const message = error.message;
    const details = error.details;
    // ...
  });

Jawa

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+KTX

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.
  std::string message = data.string_value();
  // Display the result in the UI.
  DisplayResult(message);
}

// ...

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

Jedność

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

Przed uruchomieniem aplikacji, należy włączyć App Sprawdź , aby zapewnić, że tylko aplikacje mogą uzyskać dostęp do swoich punktów końcowych wywołalnych funkcyjnych.