بازگشت به وبلاگ

پوش نوتیفیکیشن اندروید؛ مجوز، کانال اعلان و دریافت پیام

پوش نوتیفیکیشن اندروید؛ مجوز، کانال اعلان و دریافت پیام

برای ارسال پوش نوتیفیکیشن به یک اپلیکیشن native اندروید، به سه بخش نیاز دارید: دریافت و نگهداری توکن FCM در اپ، ارسال پیام از یک سرور یا سرویس واسط، و ساخت اعلان در سیستم‌عامل با رعایت مجوزها و کانال‌ها. در اندروید ۱۳ و بالاتر، اعلان‌های معمولی بدون مجوز زمان اجرا نمایش داده نمی‌شوند؛ در اندروید ۸ و بالاتر نیز هر اعلان باید به یک کانال اختصاص داده شود.

در این مقاله:

معماری ارسال پوش با FCM

در معماری رایج، اپلیکیشن پس از نصب و آماده‌شدن سرویس پیام‌رسانی، یک توکن اختصاصی از Firebase Cloud Messaging دریافت می‌کند. این توکن شناسه‌ای برای یک نمونه نصب‌شده از اپ است و نباید آن را شناسه دائمی کاربر فرض کرد. اپلیکیشن توکن را به backend شما می‌فرستد؛ backend آن را همراه با شناسه کاربر، دستگاه یا اشتراک ذخیره می‌کند و هنگام اجرای کمپین، پیام را از مسیر امن سرور به FCM می‌سپارد.

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

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

مجوز اعلان در اندروید ۱۳

از Android 13، مجوز POST_NOTIFICATIONS برای اعلان‌های معمولی یک مجوز زمان اجراست. وجود آن در فایل manifest کافی نیست؛ اپ باید در زمان مناسب از کاربر درخواست اجازه کند و نتیجه را در مسیر تجربه کاربری خود مدیریت کند. جزئیات این رفتار در مستندات مجوز اعلان اندروید توضیح داده شده است.

الگوی پیشنهادی درخواست مجوز

  1. درخواست را در اولین اجرای بی‌مقدمه نشان ندهید: ابتدا توضیح کوتاهی بدهید که اعلان چه فایده‌ای برای کاربر دارد؛ برای نمونه، اطلاع‌رسانی وضعیت سفارش.
  2. پس از یک اقدام معنادار درخواست کنید: کاربر باید بداند با اجازه‌دادن چه نوع پیامی دریافت خواهد کرد.
  3. ردشدن مجوز را پیش‌بینی کنید: اپ باید بدون اعلان هم قابل استفاده باشد و وضعیت رد مجوز را در تنظیمات یا راهنمای داخلی نشان دهد.
  4. در نسخه‌های مختلف آزمایش کنید: رفتار درخواست مجوز می‌تواند به target SDK و وضعیت نصب اپ وابسته باشد؛ آن را روی نصب تازه و ارتقای نسخه جداگانه بررسی کنید.

اگر مجوز رد شده باشد، ساختن Notification در کد به معنی نمایش قطعی آن نیست. همچنین خاموش‌بودن اعلان در سطح یک کانال یا تنظیمات کلی دستگاه می‌تواند مانع نمایش شود.

آموزش پیاده‌سازی پوش با Firebase Cloud Messaging

کانال اعلان در اندروید ۸

از Android 8، هر اعلان باید به یک Notification Channel تعلق داشته باشد. کانال، دسته‌ای قابل مدیریت برای کاربر است و اهمیت، صدا و برخی تنظیمات آن از طریق سیستم‌عامل کنترل می‌شود. نام‌گذاری کانال را بر اساس کاربرد انجام دهید، نه بر اساس هر کمپین؛ مثلاً «وضعیت سفارش» و «پیشنهادها» معمولاً از ساختن کانالی برای هر پیام قابل‌مدیریت‌تر هستند.

کانال را پیش از ارسال نخستین اعلان ایجاد کنید و شناسه‌ای پایدار برای آن در نظر بگیرید. تغییر اهمیت کانالی که قبلاً ساخته شده، ممکن است به تنظیمات قبلی کاربر وابسته باشد؛ در چنین شرایطی به‌جای تلاش برای بازنویسی انتخاب کاربر، مسیر روشنی برای مدیریت تنظیمات ارائه دهید. برای جزئیات بیشتر درباره ساختار و تنظیمات کانال، راهنمای کانال اعلان در اندروید را ببینید.

پیشنهاد برای طراحی کانال

کاربردنمونه کانالنکته اجرایی
رویداد ضروریوضعیت سفارشپیام‌ها باید محدود و دقیق باشند.
محتوای بازاریابیپیشنهادهاامکان خاموش‌کردن این کانال را محترم بشمارید.
پیام‌های فنیحساب کاربریاز ارسال اطلاعات حساس در عنوان یا متن خودداری کنید.

رفتار پیام در foreground و background

وقتی اپ در foreground است، معمولاً نباید فرض کنید سیستم‌عامل همان اعلان قابل مشاهده در background را خودکار می‌سازد. در این وضعیت، callback دریافت پیام اجرا می‌شود و اپ باید بر اساس نوع پیام تصمیم بگیرد: نمایش اعلان محلی، به‌روزرسانی رابط کاربری، یا نادیده‌گرفتن پیام تکراری.

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

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

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

اگر پیام دریافت شد:
  اگر مجوز اعلان وجود ندارد: پایان
  کانال مربوط به کاربرد پیام را پیدا یا ایجاد کن
  اگر اپ در foreground است: اعلان محلی یا به‌روزرسانی رابط را انتخاب کن
  در غیر این صورت: از مسیر مدیریت‌شده پیام استفاده کن

دریافت و نوسازی توکن

توکن FCM ممکن است تغییر کند؛ برای همین، فقط ذخیره‌کردن مقدار اولیه کافی نیست. callback نوسازی توکن را پیاده‌سازی کنید و هر مقدار جدید را با احراز هویت مناسب به backend بفرستید. در سمت سرور، توکن را برای همان نصب به‌روزرسانی کنید و در صورت امکان، زمان آخرین مشاهده، نسخه اپ و سیستم‌عامل را نیز برای عیب‌یابی نگه دارید.

چک‌لیست مدیریت توکن

  • توکن را به‌عنوان داده محرمانه مطلق تلقی نکنید، اما آن را در URL عمومی، لاگ قابل مشاهده یا متن اعلان قرار ندهید.
  • در نصب دوباره، پاک‌شدن داده‌ها و تغییر حساب کاربری، رابطه توکن با مشترک قبلی را بررسی کنید.
  • توکن نامعتبر را پس از دریافت خطای معتبر از سرویس ارسال، غیرفعال یا حذف کنید؛ صرفاً با یک بار شکست موقت این کار را انجام ندهید.
  • اگر یک کاربر چند دستگاه دارد، برای هر نصب رکورد جدا داشته باشید تا حذف یک توکن، دستگاه‌های دیگر را از بین نبرد.

برای بررسی علت‌هایی مانند توکن منقضی، کانال خاموش یا محدودیت دستگاه، راهنمای عیب‌یابی نرسیدن اعلان می‌تواند مکمل این بخش باشد.

ارسال امن و اتصال به پوشفا

کلیدهای خصوصی و اعتبارنامه‌های ارسال باید فقط روی backend یا زیرساخت امن سرویس ارسال بمانند. قرار دادن آن‌ها در APK، کد Kotlin یا Java، فایل‌های قابل دانلود، اپلیکیشن موبایل یا مرورگر به معنی افشای راز است؛ حتی مبهم‌سازی کد نیز این مشکل را حل نمی‌کند.

اپلیکیشن باید فقط اطلاعات لازم، مانند توکن تازه و شناسه داخلی نصب، را به سرور شما بفرستد. سپس backend با کنترل دسترسی، اعتبارسنجی ورودی، ثبت گزارش و سیاست حذف توکن‌های نامعتبر، پیام را از مسیر مجاز ارسال کند. اگر به جزئیات پیاده‌سازی backend و نمونه درخواست نیاز دارید، مقاله ارسال پوش با PHP و Laravel مرتبط‌تر است؛ کلید خصوصی را در هیچ نمونه سمت اپ قرار ندهید.

در محتوای پیام نیز اطلاعات شخصی، رمز، شماره کامل سفارش یا داده پزشکی قرار ندهید. لینک کلیک باید به صفحه‌ای برسد که پس از احراز هویت، جزئیات را از سرور دریافت می‌کند. برای اندازه متن، محدودیت عملی سرویس را رعایت کنید: عنوان حداکثر ۳۵ و بدنه حداکثر ۱۵۰ نویسه باشد.

چک‌لیست آزمایش و عیب‌یابی

  1. آزمایش را روی Android 8، Android 12 و Android 13 یا بالاتر انجام دهید.
  2. نصب تازه، ارتقای نسخه، رد مجوز، فعال‌بودن مجوز و خاموش‌بودن یک کانال را جداگانه تست کنید.
  3. توکن ثبت‌شده در backend را با توکن فعلی دستگاه مقایسه کنید و زمان آخرین نوسازی را ثبت کنید.
  4. یک پیام تستی در foreground و background بفرستید و بررسی کنید فقط یک اعلان ساخته می‌شود.
  5. آیکون اعلان، نام کانال، صدای آن و مسیر کلیک را روی چند سازنده دستگاه بررسی کنید.
  6. نتیجه را از گزارش ارسال، دریافت دستگاه و کلیک جدا کنید؛ موفقیت ارسال به معنی خوانده‌شدن پیام نیست.

در زمان‌بندی یا صف ارسال نیز تحویل را دائمی فرض نکنید. TTL فقط مشخص می‌کند پیام تا چه مدت برای تحویل پس از آفلاین‌بودن قابل نگهداری است و تضمین ذخیره‌شدن نامحدود یا تحویل صددرصدی نیست.

پرسش‌های متداول

آیا FCM در foreground اعلان را خودکار نشان می‌دهد؟

نه همیشه. در foreground، callback پیام به اپ می‌رسد و معمولاً باید تصمیم ساخت اعلان محلی یا به‌روزرسانی رابط را خودتان بگیرید.

آیا بدون مجوز Android 13 می‌توان پیام FCM دریافت کرد؟

ممکن است پیام به اپ برسد، اما اعلان معمولی بدون مجوز نمایش داده نمی‌شود. منطق دریافت داده و نمایش اعلان را از هم جدا طراحی کنید.

آیا توکن FCM ثابت است؟

خیر. توکن می‌تواند تغییر کند؛ callback نوسازی را ثبت کنید و مقدار جدید را به backend بفرستید.

آیا گذاشتن کلید FCM در اپلیکیشن اشکال دارد؟

کلید خصوصی یا اعتبارنامه ارسال نباید در اپ باشد. ارسال را از backend یا سرویس واسط امن انجام دهید و اپ را فقط مسئول ثبت توکن و دریافت پیام نگه دارید.