欢迎参加我们将于 2022 年 10 月 18 日举办的 Firebase 峰会(线上线下同时进行),了解 Firebase 如何帮助您加快应用开发速度、满怀信心地发布应用并在之后需要时轻松地扩大应用规模。立即报名

فراخوانی توابع از برنامه شما

Cloud Functions برای SDK های مشتری Firebase به شما امکان می دهد توابع را مستقیماً از یک برنامه Firebase فراخوانی کنید. برای فراخوانی یک تابع از برنامه خود به این روش، یک تابع HTTPS Callable را در Cloud Functions بنویسید و مستقر کنید و سپس منطق کلاینت را برای فراخوانی تابع از برنامه خود اضافه کنید.

مهم است که به خاطر داشته باشید که توابع قابل فراخوانی HTTPS مشابه توابع HTTP هستند اما یکسان نیستند . برای استفاده از توابع قابل فراخوانی HTTPS، باید از SDK کلاینت برای پلتفرم خود همراه با functions.https پشتیبان API.https (یا اجرای پروتکل) استفاده کنید. Calable ها این تفاوت های کلیدی را با توابع HTTP دارند:

  • با قابلیت فراخوانی، توکن‌های Firebase Authentication، نشانه‌های FCM، و نشانه‌های App Check، در صورت وجود، به‌طور خودکار در درخواست‌ها گنجانده می‌شوند.
  • راه‌انداز functions.https.onCall به‌طور خودکار بدنه درخواست را از فهرست خارج می‌کند و نشانه‌های تأیید اعتبار را تأیید می‌کند.

Firebase SDK for Cloud Functions نسخه 0.9.1 و بالاتر با حداقل نسخه های SDK مشتری Firebase برای پشتیبانی از عملکردهای HTTPS Callable همکاری می کند:

  • Firebase SDK برای پلتفرم های اپل 9.6.0
  • Firebase SDK برای اندروید 20.1.1
  • Firebase JavaScript SDK 8.10.1
  • Firebase Modular Web SDK نسخه 9.0

اگر می‌خواهید عملکرد مشابهی را به برنامه‌ای که بر روی پلتفرم پشتیبانی‌نشده ساخته شده است اضافه کنید، به مشخصات پروتکل https.onCall کنید. بقیه این راهنما دستورالعمل هایی در مورد نحوه نوشتن، استقرار و فراخوانی یک تابع قابل فراخوانی HTTPS برای پلتفرم های اپل، اندروید، وب، C++ و Unity ارائه می دهد.

تابع فراخوانی را بنویسید و اجرا کنید

برای ایجاد یک تابع قابل فراخوانی HTTPS از functions.https.onCall استفاده کنید. این روش دو پارامتر دارد: data و context اختیاری:

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

برای یک تابع قابل فراخوانی که یک پیام متنی را در پایگاه داده بیدرنگ ذخیره می‌کند، برای مثال، data می‌توانند حاوی متن پیام باشند، در حالی که پارامترهای context اطلاعات تأیید اعتبار کاربر را نشان می‌دهند:

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

فاصله بین مکان تابع قابل فراخوانی و مکان کلاینت تماس گیرنده می تواند تأخیر شبکه ایجاد کند. برای بهینه‌سازی عملکرد، مکان عملکرد را در صورت امکان مشخص کنید و مطمئن شوید که وقتی SDK را در سمت کلاینت مقداردهی می‌کنید، مکان تماس‌پذیر را با موقعیت مکانی تنظیم کنید.

به صورت اختیاری، می‌توانید یک گواهی برنامه چک را ضمیمه کنید تا از منابع پشتیبان خود در برابر سوء استفاده محافظت کنید، مانند تقلب در صورت‌حساب یا فیشینگ. به فعال کردن اجرای بررسی برنامه برای عملکردهای ابری مراجعه کنید.

بازگرداندن نتیجه

برای بازگرداندن داده‌ها به مشتری، داده‌هایی را برگردانید که می‌توانند JSON کدگذاری شوند. به عنوان مثال، برای برگرداندن نتیجه یک عملیات جمع:

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

برای برگرداندن داده ها پس از یک عملیات ناهمزمان، یک وعده را برگردانید. داده های برگشت داده شده توسط وعده به مشتری بازگردانده می شود. برای مثال، می‌توانید متن پاک‌سازی‌شده‌ای را که تابع قابل فراخوانی نوشته است به پایگاه داده بیدرنگ بازگردانید:

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

رسیدگی به خطاها

برای اطمینان از اینکه مشتری جزئیات خطای مفیدی را دریافت می‌کند، با پرتاب کردن (یا برگرداندن یک Promise Rejected با) نمونه‌ای از functions.https.HttpsError ، خطاها را از یک فراخوانی برگردانید.https.HttpsError. خطا دارای یک ویژگی code است که می تواند یکی از مقادیر فهرست شده در functions.https.HttpsError . خطاها همچنین دارای یک message رشته ای هستند که به طور پیش فرض یک رشته خالی است. آنها همچنین می توانند یک فیلد details اختیاری با مقدار دلخواه داشته باشند. اگر خطایی غیر از HttpsError از توابع شما پرتاب شود، کلاینت شما در عوض یک خطا با پیام INTERNAL و کد internal دریافت می کند.

به عنوان مثال، یک تابع می تواند خطاهای اعتبارسنجی و احراز هویت داده ها را با پیام های خطا ارسال کند تا به مشتری تماس گیرنده بازگردد:

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

تابع فراخوانی را اجرا کنید

پس از اینکه یک تابع قابل فراخوان کامل را در index.js ذخیره کردید، با اجرای firebase deploy همراه با سایر توابع مستقر می شود. برای استقرار فقط فراخوانی، از آرگومان --only همانطور که نشان داده شده است برای انجام استقرار جزئی استفاده کنید:

firebase deploy --only functions:addMessage

اگر هنگام استقرار توابع با خطاهای مجوز مواجه شدید، مطمئن شوید که نقش های IAM مناسب به کاربری که دستورات استقرار را اجرا می کند اختصاص داده شده است.

محیط توسعه مشتری خود را تنظیم کنید

مطمئن شوید که پیش نیازها را برآورده می کنید، سپس وابستگی ها و کتابخانه های مشتری مورد نیاز را به برنامه خود اضافه کنید.

iOS+

دستورالعمل ها را برای افزودن Firebase به برنامه Apple خود دنبال کنید.

برای نصب و مدیریت وابستگی های Firebase از Swift Package Manager استفاده کنید.

  1. در Xcode، با باز بودن پروژه برنامه، به File > Add Packages بروید.
  2. هنگامی که از شما خواسته شد، مخزن SDK پلتفرم های Apple Firebase را اضافه کنید:
  3.   https://github.com/firebase/firebase-ios-sdk
  4. کتابخانه Cloud Functions را انتخاب کنید.
  5. پس از اتمام، Xcode به طور خودکار شروع به حل و دانلود وابستگی های شما در پس زمینه می کند.

Web version 9

  1. دستورالعمل ها را برای افزودن Firebase به برنامه وب خود دنبال کنید. حتماً دستور زیر را از ترمینال خود اجرا کنید:
    npm install firebase@9.10.0 --save
    
  2. به صورت دستی هم به هسته Firebase و هم توابع Cloud نیاز دارید:

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

Web version 8

  1. دستورالعمل ها را برای افزودن Firebase به برنامه وب خود دنبال کنید.
  2. هسته Firebase و کتابخانه های کلاینت Cloud Functions را به برنامه خود اضافه کنید:
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-functions.js"></script>
    

Cloud Functions SDK نیز به صورت بسته npm در دسترس است.

  1. دستور زیر را از ترمینال خود اجرا کنید:
    npm install firebase@8.10.1 --save
    
  2. به صورت دستی به هسته Firebase و توابع Cloud نیاز دارید:
    const firebase = require("firebase");
    // Required for side-effects
    require("firebase/functions");
    

Java

  1. دستورالعمل ها را برای افزودن Firebase به برنامه Android خود دنبال کنید.

  2. در فایل Gradle ماژول (سطح برنامه) خود (معمولا <project>/<app-module>/build.gradle )، وابستگی را برای کتابخانه Android Cloud Functions اضافه کنید. توصیه می‌کنیم از Firebase Android BoM برای کنترل نسخه‌سازی کتابخانه استفاده کنید.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:30.5.0')
    
        // Add 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'
    }
    

    با استفاده از Firebase Android BoM ، برنامه شما همیشه از نسخه های سازگار کتابخانه های Firebase Android استفاده می کند.

    (جایگزین) وابستگی های کتابخانه Firebase را بدون استفاده از BoM اضافه کنید

    اگر تصمیم گرفتید از Firebase BoM استفاده نکنید، باید هر نسخه کتابخانه Firebase را در خط وابستگی آن مشخص کنید.

    توجه داشته باشید که اگر از چندین کتابخانه Firebase در برنامه خود استفاده می کنید، ما قویاً توصیه می کنیم از BoM برای مدیریت نسخه های کتابخانه استفاده کنید، که تضمین می کند همه نسخه ها سازگار هستند.

    dependencies {
        // Add 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.1.1'
    }
    

Kotlin+KTX

  1. دستورالعمل ها را برای افزودن Firebase به برنامه Android خود دنبال کنید.

  2. در فایل Gradle ماژول (سطح برنامه) خود (معمولا <project>/<app-module>/build.gradle )، وابستگی را برای کتابخانه Android Cloud Functions اضافه کنید. توصیه می‌کنیم از Firebase Android BoM برای کنترل نسخه‌سازی کتابخانه استفاده کنید.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:30.5.0')
    
        // Add 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'
    }
    

    با استفاده از Firebase Android BoM ، برنامه شما همیشه از نسخه های سازگار کتابخانه های Firebase Android استفاده می کند.

    (جایگزین) وابستگی های کتابخانه Firebase را بدون استفاده از BoM اضافه کنید

    اگر تصمیم گرفتید از Firebase BoM استفاده نکنید، باید هر نسخه کتابخانه Firebase را در خط وابستگی آن مشخص کنید.

    توجه داشته باشید که اگر از چندین کتابخانه Firebase در برنامه خود استفاده می کنید، ما قویاً توصیه می کنیم از BoM برای مدیریت نسخه های کتابخانه استفاده کنید، که تضمین می کند همه نسخه ها سازگار هستند.

    dependencies {
        // Add 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.1.1'
    }
    

Dart

  1. دستورالعمل ها را دنبال کنید تا Firebase را به برنامه Flutter خود اضافه کنید .

  2. از ریشه پروژه Flutter خود، دستور زیر را برای نصب افزونه اجرا کنید:

    flutter pub add cloud_functions
    
  3. پس از تکمیل، برنامه Flutter خود را بازسازی کنید:

    flutter run
    
  4. پس از نصب، می توانید با وارد کردن پلاگین cloud_functions در کد دارت خود به آن دسترسی پیدا کنید:

    import 'package:cloud_functions/cloud_functions.dart';
    

C++

برای C++ با اندروید :

  1. دستورالعمل ها را برای افزودن Firebase به پروژه C++ خود دنبال کنید.
  2. کتابخانه firebase_functions را به فایل CMakeLists.txt خود اضافه کنید.

برای C++ با پلتفرم های اپل :

  1. دستورالعمل ها را برای افزودن Firebase به پروژه C++ خود دنبال کنید.
  2. غلاف توابع ابری را به فایل پاد خود اضافه کنید: Podfile
    pod 'Firebase/Functions'
  3. فایل را ذخیره کنید، سپس اجرا کنید:
    pod install
  4. هسته Firebase و چارچوب‌های Cloud Functions را از Firebase C++ SDK به پروژه Xcode خود اضافه کنید.
    • firebase.framework
    • firebase_functions.framework

وحدت

  1. دستورالعمل ها را دنبال کنید تا Firebase را به پروژه Unity خود اضافه کنید .
  2. FirebaseFunctions.unitypackage را از Firebase Unity SDK به پروژه Unity خود اضافه کنید.

SDK مشتری را راه اندازی کنید

نمونه ای از توابع ابری را راه اندازی کنید:

سریع

lazy var functions = Functions.functions()

هدف-C

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

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

Web version 9

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

Java

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

Kotlin+KTX

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

Dart

final functions = FirebaseFunctions.instance;

C++

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

وحدت

functions = Firebase.Functions.DefaultInstance;

تابع را فراخوانی کنید

سریع

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

هدف-C

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

Web version 8

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

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

Java

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

Dart

final result =
    await FirebaseFunctions.instance.httpsCallable('addMessage').call();

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

وحدت

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

رسیدگی به خطاهای مشتری

در صورتی که سرور خطایی را مرتکب شده باشد یا وعده حاصله رد شود، کلاینت یک خطا دریافت می کند.

اگر خطای بازگردانده شده توسط تابع از نوع function.https.HttpsError ، کلاینت code خطا، message و details خطای سرور را دریافت می کند. در غیر این صورت، خطا حاوی پیام INTERNAL و کد INTERNAL است. راهنمای نحوه رسیدگی به خطاها در عملکرد قابل فراخوانی خود را ببینید.

سریع

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

هدف-C

if (error) {
  if ([error.domain isEqual:@"com.firebase.functions"]) {
    FIRFunctionsErrorCode code = error.code;
    NSString *message = error.localizedDescription;
    NSObject *details = error.userInfo[@"details"];
  }
  // ...
}

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

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

Java

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 { task ->
        if (!task.isSuccessful) {
            val e = task.exception
            if (e is FirebaseFunctionsException) {
                val code = e.code
                val details = e.details
            }
        }
    }

Dart

try {
  final result =
      await FirebaseFunctions.instance.httpsCallable('addMessage').call();
} on FirebaseFunctionsException catch (error) {
  print(error.code);
  print(error.details);
  print(error.message);
}

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

وحدت

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

قبل از اینکه برنامه خود را راه اندازی کنید، باید App Check را فعال کنید تا مطمئن شوید که فقط برنامه های شما می توانند به نقاط پایانی عملکرد قابل فراخوانی شما دسترسی داشته باشند.