Memanggil fungsi dari aplikasi Anda

Dengan SDK klien Cloud Functions for Firebase, Anda dapat memanggil fungsi langsung dari aplikasi Firebase. Untuk memanggil fungsi dari aplikasi Anda dengan cara ini, tulis dan terapkan fungsi Callable HTTPS di Cloud Functions, lalu tambahkan logika klien untuk memanggil fungsi dari aplikasi Anda.

Fungsi Callable mirip dengan fungsi HTTP lainnya, dengan fitur tambahan ini:

  • Dengan callable, token Firebase Authentication dan FCM, jika tersedia, akan otomatis disertakan dalam permintaan.
  • Pemicu functions.https.onCall akan melakukan deserialisasi isi permintaan dan memvalidasi token autentikasi secara otomatis.

Firebase SDK untuk Cloud Functions v0.9.1 dan yang lebih tinggi memiliki keterkaitan operasi dengan versi minimum SDK klien Firebase berikut untuk mendukung fungsi Callable HTTPS:

  • Firebase SDK untuk iOS 5.17.0
  • Firebase SDK untuk Android 16.1.0
  • Firebase JavaScript SDK 5.8.0

Jika Anda ingin menambahkan fungsi serupa ke aplikasi yang dikembangkan pada platform yang tidak didukung, baca Spesifikasi Protokol untuk https.onCall. Bagian lainnya dalam panduan ini memberikan petunjuk tentang cara menulis, menerapkan, dan memanggil fungsi callable HTTPS untuk iOS, Android, web, C++, dan Unity.

Menulis dan menerapkan fungsi callable

Gunakan functions.https.onCall untuk membuat fungsi callable HTTPS. Metode ini mengambil 2 parameter: data, dan context opsional:

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

Untuk fungsi callable yang menyimpan pesan teks ke Realtime Database, misalnya, data dapat berisi teks pesan, sementara parameter context mewakili informasi autentikasi pengguna:

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

Jarak antara lokasi fungsi callable dan lokasi klien yang melakukan panggilan dapat menghasilkan latensi jaringan. Untuk mengoptimalkan performa, pertimbangkan untuk menentukan lokasi fungsi jika ada dan pastikan untuk menyelaraskan lokasi callable dengan lokasi yang ditetapkan saat Anda menginisialisasi SDK di sisi klien.

Mengirim kembali hasilnya

Untuk mengirim data kembali ke klien, tampilkan data yang bisa dienkode JSON. Misalnya, untuk menampilkan hasil operasi penjumlahan:

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

Untuk menampilkan data setelah operasi asinkron, tampilkan sebuah promise. Data yang ditampilkan oleh promise tersebut akan dikirim kembali ke klien. Misalnya, Anda dapat menampilkan teks bersih yang dapat ditulisi oleh fungsi callable ke 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 };
})

Menangani error

Untuk memastikan klien mendapatkan detail error yang berguna, tampilkan error dari fungsi callable dengan menunjukkan (atau menampilkan Promise yang ditolak oleh) instance functions.https.HttpsError. Error tersebut memiliki atribut code yang dapat berupa salah satu nilai yang tercantum di functions.https.HttpsError. Error tersebut juga memiliki message string, yang secara default berupa string kosong. Error ini juga dapat memiliki kolom details opsional dengan nilai arbitrer. Jika error selain HttpsError ditampilkan oleh fungsi Anda, klien akan menerima error dengan pesan INTERNAL dan kode internal.

Misalnya, fungsi dapat menampilkan error pada proses validasi data dan autentikasi dengan pesan error, yang akan ditampilkan ke klien yang melakukan panggilan:

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

Menerapkan fungsi callable

Setelah Anda menyimpan fungsi callable yang telah selesai di dalam index.js, fungsi tersebut akan diterapkan bersamaan dengan semua fungsi lainnya saat Anda menjalankan firebase deploy. Untuk menerapkan callable saja, gunakan argumen --only seperti yang ditunjukkan untuk menjalankan penerapan sebagian:

$ firebase deploy --only functions:addMessage

Menyiapkan lingkungan pengembangan klien Anda

Pastikan Anda memenuhi prasyarat, serta tambahkan dependensi dan library klien yang dibutuhkan ke aplikasi Anda.

iOS

  1. Ikuti petunjuk untuk menambahkan Firebase ke aplikasi iOS Anda.
  2. Tambahkan pod Cloud Functions ke Podfile Anda
    pod 'Firebase/Core'
    pod 'Firebase/Functions'
  3. Simpan file dan jalankan pod install.

Web

  1. Ikuti petunjuk untuk menambahkan Firebase ke aplikasi Web Anda.
  2. Tambahkan library klien Firebase dan Cloud Functions ke aplikasi Anda:
    <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>
    
    Cloud Functions SDK juga tersedia sebagai paket npm.
    npm install firebase@5.8.4 --save
    
    Anda harus meminta Firebase dan Cloud Functions secara manual.
    const firebase = require("firebase");
    // Required for side-effects
    require("firebase/functions");
    

Android

  1. Ikuti petunjuk untuk menambahkan Firebase ke aplikasi Android Anda.
  2. Tambahkan library Android untuk Cloud Functions ke file app/build.gradle:
    implementation 'com.google.firebase:firebase-functions:16.3.0'

C++

Untuk C++ dengan Android:

  1. Ikuti petunjuk untuk menambahkan Firebase ke project C++ Anda.
  2. Tambahkan library Android untuk Cloud Functions ke file app/build.gradle:
    implementation 'com.google.firebase:firebase-functions:16.3.0'
  3. Hubungkan library statis libfirebase_app.a dan libfirebase_functions.a dari C++ SDK.

Untuk C++ dengan iOS:

  1. Ikuti petunjuk untuk menambahkan Firebase ke project C++ Anda.
  2. Tambahkan pod Cloud Functions ke Podfile Anda
    pod 'Firebase/Core'
    pod 'Firebase/Functions'
  3. Simpan file dan jalankan pod install.
  4. Tambahkan firebase.framework dan firebase_functions.framework dari C++ SDK ke project Xcode Anda.

Unity

  1. Download Firebase Unity SDK.
  2. Ikuti petunjuk untuk menambahkan Firebase ke project Unity Anda.
  3. Pilih item menu Assets > Import Package > Custom Package.
  4. Impor paket FirebaseFunctions.unitypackage dari Firebase Unity SDK, yang telah didownload sebelumnya.
  5. Saat jendela Import Unity Package muncul, klik tombol Import.

Menginisialisasi SDK klien

Menginisialisasi instance 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;

Memanggil fungsi

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

Menangani error pada klien

Klien akan menerima error jika server menampilkan error atau promise yang dihasilkan ditolak.

Jika error yang ditampilkan oleh fungsi berjenis function.https.HttpsError, klien akan menerima error code, message, dan details dari error server. Jika tidak, error akan berisi pesan INTERNAL dan kode INTERNAL. Baca panduan untuk menangani error dalam fungsi callable Anda.

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

Kirim masukan tentang...

Butuh bantuan? Kunjungi halaman dukungan kami.