محیط سرور و FCM شما

سمت سرور Firebase Cloud Messaging از دو جزء تشکیل شده است:

  • پشتیبان FCM ارائه شده توسط Google.
  • سرور برنامه یا سایر محیط های سرور قابل اعتمادی که منطق سرور شما در آن اجرا می شود، مانند Cloud Functions برای Firebase یا سایر محیط های ابری تحت مدیریت Google.

سرور برنامه یا محیط سرور مورد اعتماد شما درخواست‌های پیام را به پشتیبان FCM ارسال می‌کند، که سپس پیام‌ها را به برنامه‌های مشتری در حال اجرا در دستگاه‌های کاربران هدایت می‌کند.

الزامات برای محیط سرور قابل اعتماد

محیط سرور برنامه شما باید معیارهای زیر را داشته باشد:

  • قادر به ارسال درخواست های پیام با فرمت مناسب به باطن FCM.
  • قادر به رسیدگی به درخواست ها و ارسال مجدد آنها با استفاده از پشتوانه نمایی.
  • قادر به ذخیره ایمن اعتبار مجوز سرور و نشانه های ثبت مشتری.
  • برای پروتکل XMPP (در صورت استفاده)، سرور باید بتواند شناسه های پیام را برای شناسایی منحصر به فرد هر پیامی که ارسال می کند ایجاد کند (پشتیبانی FCM HTTP شناسه های پیام را تولید می کند و آنها را در پاسخ برمی گرداند). شناسه پیام XMPP باید برای هر شناسه فرستنده منحصر به فرد باشد.

انتخاب گزینه سرور

شما باید در مورد راهی برای تعامل با سرورهای FCM تصمیم بگیرید: یا با استفاده از Firebase Admin SDK یا پروتکل‌های خام. Firebase Admin SDK به دلیل پشتیبانی از زبان‌های برنامه‌نویسی محبوب و روش‌های راحت آن برای مدیریت احراز هویت و مجوز، روش پیشنهادی است.

گزینه های تعامل با سرورهای FCM شامل موارد زیر است:
  • Firebase Admin SDK که از Node ، Java ، Python ، C# و Go پشتیبانی می کند.
  • API FCM HTTP v1 ، که به روزترین گزینه در میان گزینه های پروتکل است، با مجوز ایمن تر و قابلیت های پیام رسانی بین پلتفرمی انعطاف پذیر (Firebase Admin SDK مبتنی بر این پروتکل است و تمام مزایای ذاتی آن را ارائه می دهد). از آنجا که ویژگی‌های جدید معمولاً فقط به API HTTP v1 اضافه می‌شوند، توصیه می‌کنیم از این API برای بیشتر موارد استفاده استفاده کنید.
  • پروتکل HTTP قدیمی . به پروژه های جدید اکیداً توصیه می شود که API FCM v1 HTTP را به جای پروتکل قدیمی استفاده کنند.
  • پروتکل سرور XMPP قدیمی . به پروژه های جدید اکیداً توصیه می شود که API FCM v1 HTTP را به جای پروتکل قدیمی استفاده کنند.

Firebase Admin SDK برای FCM

Admin FCM API احراز هویت با باطن را انجام می دهد و ارسال پیام و مدیریت اشتراک موضوع را تسهیل می کند. با Firebase Admin SDK، می توانید:

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

Admin Node.js SDK روش هایی را برای ارسال پیام به گروه های دستگاه ارائه می دهد.

برای تنظیم Firebase Admin SDK، به افزودن Firebase Admin SDK به سرور خود مراجعه کنید . اگر قبلاً یک پروژه Firebase دارید، با افزودن SDK شروع کنید . همچنین، مطمئن شوید که Cloud Messagin API را در صفحه تنظیمات Cloud Messaging برای پروژه خود فعال کنید. سپس، هنگامی که Firebase Admin SDK نصب شد، می توانید شروع به نوشتن منطق برای ایجاد درخواست های ارسال کنید .

پروتکل های سرور FCM

در حال حاضر FCM این پروتکل های سرور خام را ارائه می دهد:

سرور برنامه شما می تواند از این پروتکل ها به طور جداگانه یا پشت سر هم استفاده کند. از آنجایی که به روزترین و منعطف ترین برای ارسال پیام به چندین پلتفرم است، API FCM HTTP v1 در هر کجا که امکان پذیر باشد توصیه می شود. اگر الزامات شما شامل ارسال پیام بالادستی از دستگاه ها به سرور است، باید پروتکل XMPP را پیاده سازی کنید.

پیام‌های XMPP به روش‌های زیر با پیام‌رسانی HTTP متفاوت است:

  • پیام های بالادستی/پایین دستی
    • HTTP: فقط پایین دست، ابر به دستگاه.
    • XMPP: بالادست و پایین دست (دستگاه به ابر، ابر به دستگاه).
  • پیام رسانی (همزمان یا ناهمزمان)
    • HTTP: همزمان. سرورهای برنامه پیام ها را به عنوان درخواست HTTP POST ارسال می کنند و منتظر پاسخ می مانند. این مکانیسم همزمان است و فرستنده را از ارسال پیام دیگری تا زمان دریافت پاسخ مسدود می کند.
    • XMPP: ناهمزمان. سرورهای برنامه پیام‌ها را به/از همه دستگاه‌های خود با سرعت کامل از طریق اتصالات XMPP مداوم ارسال/دریافت می‌کنند. سرور اتصال XMPP اعلان‌های تأیید یا خرابی (در قالب پیام‌های XMPP ویژه ACK و NACK JSON-encoded XMPP) را به‌صورت ناهمزمان ارسال می‌کند.
  • JSON
    • HTTP: پیام های JSON به عنوان HTTP POST ارسال می شوند.
    • XMPP: پیام های JSON که در پیام های XMPP محصور شده اند.
  • متن ساده
    • HTTP: پیام های متنی ساده به عنوان HTTP POST ارسال می شوند.
    • XMPP: پشتیبانی نمی شود.
  • ارسال چندپخشی پایین دست به چندین توکن ثبت نام.
    • HTTP: در قالب پیام JSON پشتیبانی می شود.
    • XMPP: پشتیبانی نمی شود.

پیاده سازی پروتکل سرور HTTP

برای ارسال پیام، سرور برنامه یک درخواست POST با سربرگ HTTP و بدنه HTTP متشکل از جفت‌های مقدار کلید JSON صادر می‌کند. برای جزئیات بیشتر در مورد گزینه‌های سرصفحه و بدنه، به ساخت درخواست‌های ارسال سرور برنامه مراجعه کنید

پیاده سازی پروتکل سرور XMPP

بار JSON برای پیام‌های FCM مشابه پروتکل HTTP است، با استثنائات زیر:

  • هیچ پشتیبانی برای چندین گیرنده وجود ندارد.
  • FCM فیلد message_id را اضافه می کند که لازم است. این شناسه پیام را در یک اتصال XMPP به طور منحصر به فرد شناسایی می کند. ACK یا NACK از FCM از message_id برای شناسایی پیام ارسال شده از سرورهای برنامه به FCM استفاده می کند. بنابراین، مهم است که این message_id نه تنها منحصر به فرد (در هر شناسه فرستنده )، بلکه همیشه وجود داشته باشد.
  • XMPP از کلید سرور برای تأیید اتصال دائمی به FCM استفاده می کند. برای اطلاعات بیشتر به مجوز ارسال درخواست ها مراجعه کنید.

علاوه بر پیام‌های معمولی FCM، پیام‌های کنترلی ارسال می‌شوند که با فیلد message_type در شی JSON نشان داده می‌شوند. مقدار می تواند "ack" یا "nack" یا "control" باشد (به فرمت های زیر مراجعه کنید). هر پیام FCM با message_type ناشناخته می تواند توسط سرور شما نادیده گرفته شود.

برای هر پیام دستگاهی که سرور برنامه شما از FCM دریافت می کند، باید یک پیام ACK ارسال کند. هرگز نیازی به ارسال پیام NACK ندارد. اگر برای پیامی ACK ارسال نکنید، دفعه بعد که یک اتصال XMPP جدید برقرار شود، FCM دوباره آن را ارسال می‌کند، مگر اینکه ابتدا پیام منقضی شود.

FCM همچنین برای هر پیام سرور به دستگاه یک ACK یا NACK ارسال می کند. اگر هیچکدام را دریافت نکردید، به این معنی است که اتصال TCP در اواسط عملیات بسته شده است و سرور شما باید پیام ها را دوباره ارسال کند. برای جزئیات به کنترل جریان مراجعه کنید.

برای فهرستی از تمام پارامترهای پیام به مرجع پروتکل مراجعه کنید.

فرمت درخواست

پیام با بار - پیام اعلان

در اینجا یک بند XMPP برای پیام اعلان وجود دارد:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
     "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
     "notification": {
        "title": "Portugal vs. Denmark”,
        "body”: "5 to 1”
      },
      "time_to_live":"600"
  }
  </gcm>
</message>

پیام با بار - پیام داده

در اینجا یک مصراع XMPP حاوی پیام JSON از یک سرور برنامه به FCM است:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "to":"REGISTRATION_ID",  // "to" replaces "registration_ids"
      "message_id":"m-1366082849205" // new required field
      "data":
      {
          "hello":"world",
      }
      "time_to_live":"600",
  }
  </gcm>
</message>

فرمت پاسخ

پاسخ FCM می تواند سه شکل ممکن داشته باشد. اولین مورد یک پیام معمولی "Ack" است. اما زمانی که پاسخ حاوی خطا باشد، پیام به 2 شکل مختلف وجود دارد که در زیر توضیح داده شده است.

پیام ACK

در اینجا یک مصراع XMPP حاوی پیام ACK/NACK از FCM به سرور برنامه است:

<message id="">
  <gcm xmlns="google:mobile:data">
  {
      "from":"REGID",
      "message_id":"m-1366082849205"
      "message_type":"ack"
  }
  </gcm>
</message>

پیام NACK

خطای NACK یک پیام معمولی XMPP است که در آن پیام وضعیت message_type "nack" است. یک پیام NACK شامل:

  • یک کد خطای NACK.
  • شرح خطای NACK.

در زیر چند نمونه آورده شده است.

ثبت نام بد:

<message>
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"SomeInvalidRegistrationToken",
    "error":"BAD_REGISTRATION",
    "error_description":"Invalid token on 'to' field: SomeInvalidRegistrationId"
  }
  </gcm>
</message>

JSON نامعتبر:

<message>
 <gcm xmlns="google:mobile:data">
 {
   "message_type":"nack",
   "message_id":"msgId1",
   "from":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
   "error":"INVALID_JSON",
   "error_description":"InvalidJson: JSON_TYPE_ERROR : Field \"time_to_live\" must be a JSON java.lang.Number: abc"
 }
 </gcm>
</message>

نرخ پیام دستگاه بیش از حد:

<message id="...">
  <gcm xmlns="google:mobile:data">
  {
    "message_type":"nack",
    "message_id":"msgId1",
    "from":"REGID",
    "error":"DEVICE_MESSAGE_RATE_EXCEEDED",
    "error_description":"Downstream message rate exceeded for this registration id"
  }
  </gcm>
</message>

برای فهرست کامل کدهای خطای NACK به مرجع سرور مراجعه کنید. مگر اینکه خلاف آن مشخص شده باشد، یک پیام NACK نباید دوباره امتحان شود. کدهای خطای غیرمنتظره NACK باید مانند INTERNAL_SERVER_ERROR رفتار شود.

خطای بند

شما همچنین می توانید یک خطای بند در موارد خاص دریافت کنید. یک خطای بند شامل:

  • کد خطای Stanza.
  • شرح خطای بند (متن آزاد).

مثلا:

<message id="3" type="error" to="123456789@fcm.googleapis.com/ABC">
  <gcm xmlns="google:mobile:data">
     {"random": "text"}
  </gcm>
  <error code="400" type="modify">
    <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
      InvalidJson: JSON_PARSING_ERROR : Missing Required Field: message_id\n
    </text>
  </error>
</message>

پیام ها را کنترل کنید

به طور دوره ای، FCM باید یک اتصال را ببندد تا تعادل بار را انجام دهد. قبل از اینکه اتصال را ببندد، FCM یک پیام CONNECTION_DRAINING ارسال می کند تا نشان دهد که اتصال در حال تخلیه است و به زودی بسته خواهد شد. «تخلیه» به قطع جریان پیام‌هایی که به یک اتصال وارد می‌شوند، اشاره دارد، اما اجازه می‌دهد هر چیزی که از قبل در خط لوله است ادامه یابد. هنگامی که یک پیام CONNECTION_DRAINING دریافت می کنید، باید فوراً شروع به ارسال پیام به یک اتصال FCM دیگر کنید و در صورت لزوم یک اتصال جدید را باز کنید. با این حال، باید اتصال اصلی را باز نگه دارید و به دریافت پیام هایی که ممکن است از طریق اتصال بیایند (و ACK کردن آنها) ادامه دهید - FCM کنترل می کند که وقتی اتصال آماده است، اتصال را شروع می کند.

پیام CONNECTION_DRAINING به این صورت است:

<message>
  <data:gcm xmlns:data="google:mobile:data">
  {
    "message_type":"control"
    "control_type":"CONNECTION_DRAINING"
  }
  </data:gcm>
</message>

CONNECTION_DRAINING در حال حاضر تنها control_type پشتیبانی شده است.

کنترل جریان

هر پیامی که به FCM ارسال می شود یک پاسخ ACK یا NACK دریافت می کند. پیام‌هایی که یکی از این پاسخ‌ها را دریافت نکرده‌اند در حالت تعلیق در نظر گرفته می‌شوند. اگر تعداد پیام‌های معلق به 100 برسد، سرور برنامه باید ارسال پیام‌های جدید را متوقف کند و منتظر بماند تا FCM برخی از پیام‌های معلق موجود را همانطور که در شکل 1 نشان داده شده است تأیید کند:

نمودار دقیق جریان کنترل بین FCM و سرور برنامه

شکل 1. جریان پیام/آک.

برعکس، برای جلوگیری از بارگذاری بیش از حد سرور برنامه، FCM ارسال را متوقف می‌کند، اگر پیام‌های تأیید نشده زیاد باشد. بنابراین، سرور برنامه باید پیام‌های بالادستی دریافت شده از برنامه مشتری از طریق FCM را در اسرع وقت «ACK» کند تا جریان پیام‌های دریافتی را ثابت نگه دارد. محدودیت پیام معلق ذکر شده در مورد این ACK ها اعمال نمی شود. حتی اگر تعداد پیام‌های معلق به 100 برسد، سرور برنامه باید به ارسال ACK برای پیام‌های دریافتی از FCM ادامه دهد تا از ارسال پیام‌های بالادستی جدید جلوگیری کند.

ACK ها فقط در چارچوب یک اتصال معتبر هستند. اگر قبل از تأیید پیام، اتصال بسته شود، سرور برنامه باید منتظر بماند تا FCM قبل از تأیید مجدد پیام بالادستی را ارسال کند. به طور مشابه، تمام پیام‌های معلقی که برای آنها ACK/NACK از FCM قبل از بسته شدن اتصال دریافت نشده است، باید دوباره ارسال شوند.