زیرساخت فنی وب پوش نوتیفیکیشن؛ از اشتراک و VAPID تا تحویل و عیبیابی
زیرساخت وب پوش نوتیفیکیشن فقط یک درخواست ارسال نیست. کاربر باید مجوز بدهد، اشتراک معتبر ایجاد شود، سرور پیام را به سرویس پوش تحویل دهد و مرورگر آن را دریافت و نمایش دهد. خطا در هر مرحله میتواند نتیجه متفاوتی بسازد؛ بنابراین پاسخ موفق API بهتنهایی اثبات نمیکند پیام روی دستگاه دیده شده است. این راهنما مسیر کامل را برای توسعهدهندهای توضیح میدهد که میخواهد وب پوش قابل نگهداری و قابل عیبیابی بسازد.
- اجزای زیرساخت و تفاوت Firebase
- مجوز و چرخه عمر اشتراک
- VAPID، رمزنگاری و امنیت
- مسیر دریافت، نمایش و کلیک
- TTL، آفلاین و پیام تکراری
- جدول عیبیابی
- راهاندازی و نگهداری در پوشفا
- پرسشهای متداول
اجزای زیرساخت وب پوش و تفاوت Firebase
در Web Push استاندارد، صفحه سایت درخواست عضویت را آغاز میکند. سرویسورکر بهعنوان بخش رویدادمحور مرورگر، دریافت پیام را مدیریت میکند. اشتراک شامل نشانی endpoint و اطلاعات رمزنگاری است؛ سرور برنامه با کتابخانه معتبر، داده را رمز میکند و به endpoint میفرستد. سرویس پوش واسطه ارتباط با مرورگر است. در نهایت سرویسورکر میتواند پوش نوتیفیکیشن را نمایش دهد و مقصد کلیک را باز کند.
| جزء | مسئولیت | نشانه قابل بررسی |
|---|---|---|
| صفحه سایت | توضیح عضویت و دریافت رضایت | وضعیت مجوز و نتیجه ثبت |
| سرویسورکر | دریافت رویداد، نمایش و کلیک | scope، نسخه و خطای اجرا |
| سرور برنامه | هدفگیری، ساخت پیام و ارسال | شناسه پیام و پاسخ سرویس |
| سرویس پوش | انتقال پیام به مرورگر | پاسخ پذیرش یا رد درخواست |
| دستگاه کاربر | اعمال تنظیمات سیستم و نمایش | گزارش نمایش، در صورت پشتیبانی |
Firebase Cloud Messaging لایه ارسال و SDK خود را دارد. توکن FCM با شیء PushSubscription یکی نیست و نباید آنها را در endpoint یا کتابخانه اشتباه استفاده کرد. در یک پیادهسازی مستقیم Web Push، سرور با endpoint اشتراک کار میکند؛ در مسیر FCM، قرارداد Firebase و توکن همان پروژه ملاک است. پوشفا تنظیمات و مسیر ارسال خود را مدیریت میکند؛ نمونه کد عمومی Web Push جایگزین بیواسطه SDK پوشفا نیست.
مجوز و چرخه عمر اشتراک
درخواست مجوز را بعد از توضیح ارزش عضویت و یک اقدام روشن کاربر، مثل کلیک روی «موجود شد خبرم کن»، نمایش دهید. مجوز مرورگر سه وضعیت رایج دارد: تصمیمنگرفته، مجاز و مسدود. تکرار درخواست پس از مسدودشدن، راهی برای دورزدن انتخاب کاربر نیست. همچنین وضعیت مجاز به معنی ثبت موفق اشتراک در سرور شما نیست؛ نتیجه مرحله ثبت را جداگانه بررسی کنید.
- سایت عمومی را روی HTTPS ارائه کنید و پشتیبانی APIها را در مرورگر بررسی کنید.
- سرویسورکر را روی همان مبدأ و با scope مناسب ثبت کنید؛ پاسخ فایل باید JavaScript باشد، نه صفحه ورود یا HTML خطا.
- اشتراک یا توکن موجود را از مسیر SDK بخوانید؛ فقط در صورت نیاز اشتراک تازه بسازید.
- اشتراک را به سرویس و مخاطب درست متصل کنید و زمان آخرین بهروزرسانی را نگه دارید.
- هنگام بازگشت کاربر، تغییر توکن را همگام کنید. اشتراک نامعتبر را از ارسالهای بعدی کنار بگذارید.
مجوز به مبدأ سایت وابسته است؛ عضویت دامنه اصلی خودکار به زیردامنه منتقل نمیشود. یک کاربر میتواند روی چند مرورگر یا دستگاه چند اشتراک داشته باشد. در نتیجه «تعداد توکن» لزوماً «تعداد افراد» نیست. خروج از حساب یا تغییر مالک دستگاه نیز باید در اتصال شناسه کاربر به اشتراک لحاظ شود تا پیام شخصی به فرد بعدی نرسد.
VAPID، رمزنگاری و امنیت کلیدها
VAPID برای معرفی سرور ارسالکننده در Web Push است. کلید عمومی میتواند در فرایند اشتراک استفاده شود؛ کلید خصوصی باید در سرور بماند. کلیدهای مربوط به رمزکردن محتوای هر اشتراک با جفت کلید VAPID یکسان نیستند. احراز هویت فرستنده، رمزنگاری داده و مجوز دریافت کاربر سه مسئولیت جدا هستند؛ داشتن یکی جای دیگری را نمیگیرد.
رمزنگاری را دستی پیادهسازی نکنید. از کتابخانه سازگار با استاندارد استفاده کنید، خطاهای آن را ثبت کنید و اندازه payload را کنترل کنید. endpoint، توکن و اطلاعات مخاطب را در لاگ عمومی، ابزار تحلیل سمت مرورگر یا نشانی قابل اشتراک قرار ندهید. کلید خصوصی API پوشفا و حساب سرویس Firebase نیز نباید داخل JavaScript یا مخزن عمومی منتشر شوند.
برای endpoint ثبت اشتراک، اعتبارسنجی ورودی، محدودیت نرخ و کنترل مالکیت سرویس لازم است. اگر کاربر با کوکی احراز هویت میشود، محافظت CSRF را نیز در نظر بگیرید. هر کسی که شناسه یک مخاطب را ارسال میکند نباید بتواند اشتراک آن مخاطب را تصاحب کند؛ شیوه اتصال Alias به سطح اعتماد سامانه شما وابسته است.
از دریافت پیام تا نمایش و کلیک
سرویسورکر دائماً روشن نیست؛ مرورگر آن را برای رسیدگی به رویداد فعال میکند. کارهای ناهمگام مرتبط با رویداد push باید در طول عمر همان رویداد نگه داشته شوند؛ در پیادهسازی مستقیم، event.waitUntil برای این منظور استفاده میشود. خطا در تبدیل payload یا نمایش تصویر نباید بیصدا نادیده گرفته شود. برای تصویر اختیاری، نمایش متن و آیکن جایگزین را پیشبینی کنید.
در مسیر Firebase، رفتار پیام notification و data-only یکسان نیست. اگر هم SDK و هم کد سفارشی یک پیام را نمایش دهند، کاربر ممکن است دو پوش نوتیفیکیشن ببیند. مالک نمایش را برای هر نوع پیام مشخص کنید. در پوشفا تنظیمات گزارش و مسیرهای SDK را طبق مستندات همان نسخه به کار ببرید و رفتار سرویسورکر را بدون بررسی جریان کامل تغییر ندهید.
| وضعیت | چه چیزی را نشان میدهد؟ | چه چیزی را ثابت نمیکند؟ |
|---|---|---|
| ارسال پذیرفتهشده | درخواست در سرویس ارسال پذیرفته شده | نمایش روی دستگاه |
| نمایش ثبتشده | نمایش در مسیر قابل گزارش ثبت شده | خواندهشدن متن توسط انسان |
| کلیک ثبتشده | تعامل با پوش نوتیفیکیشن ثبت شده | خرید یا تکمیل هدف |
| تبدیل | رویداد هدف در سامانه مقصد ثبت شده | اثر افزایشی کمپین بدون مقایسه |
مقصد کلیک را به مسیر مرتبط محدود کنید؛ برای نمونه پیام سفارش باید همان سفارش را پس از احراز هویت نشان دهد. اطلاعات حساس را در متن قابل نمایش روی صفحه قفل قرار ندهید. اگر گزارش کلیک فعال است، مسیر رهگیری را هنگام بازکردن لینک یا دکمه دور نزنید.
TTL، دستگاه آفلاین و پیامهای تکراری
TTL مدت اعتبار پیام است، نه تضمین زمان تحویل. برای تخفیفی که دو ساعت دیگر تمام میشود، نگهداری پیام برای چند روز منطقی نیست. اگر دستگاه در بازه اعتبار به شبکه برگردد، امکان تحویل وجود دارد؛ اما اشتراک نامعتبر، محدودیت دستگاه، تنظیمات سیستم یا شرایط سرویس میتوانند همچنان مانع شوند. TTL و انقضای خود اشتراک نیز دو مفهوم متفاوتاند.
در FCM، TTL صفر یعنی پیام فقط در صورت امکان تحویل فوری ارسال شود و برای تحویل بعدی ذخیره نشود. سقف و رفتار نگهداری را برای پلتفرم و نوع پیام در مستندات بررسی کنید. برای وضعیتهایی مثل آخرین قیمت یا آخرین وضعیت سفارش، جایگزینی پیام قبلی با شناسه مشترک میتواند مناسب باشد؛ برای رویدادهای مستقل مثل چند رسید مجزا، ادغام پیامها ممکن است اطلاعات لازم را پنهان کند.
تلاش مجدد را با تأخیر افزایشی، کمی تصادفیسازی و رعایت Retry-After انجام دهید. retry نامحدود برای توکن نامعتبر منابع را هدر میدهد. از طرف دیگر، timeout همیشه به معنی نرسیدن درخواست نیست؛ اگر سرور پاسخ را دریافت نکرده باشد، ارسال دوباره ممکن است پیام تکراری بسازد. شناسه پایدار رویداد و ثبت تلاشها به تشخیص این وضعیت کمک میکند.
جدول عیبیابی وب پوش
| نشانه | اولین بررسی | اقدام مناسب |
|---|---|---|
| اشتراک ساخته نمیشود | HTTPS، مجوز و ثبت سرویسورکر | خطای مرورگر و پاسخ فایل worker را بررسی کنید |
| رد درخواست ارسال | اعتبارنامه، پروژه و قالب payload | کد و متن خطای سرویس را ملاک قرار دهید |
| اشتراک منقضی یا نامعتبر | پاسخ صریح سرویس به همان اشتراک | از ارسال بعدی حذف و هنگام بازگشت کاربر همگام شود |
| پذیرش ارسال بدون گزارش نمایش | شبکه، TTL، تنظیمات دستگاه و فعالبودن گزارش | روی دستگاه واقعی مسیر نمایش را بررسی کنید |
| پیام تکراری | نمایش همزمان توسط SDK و کد سفارشی یا retry | مالک نمایش و شناسه رویداد را مشخص کنید |
| محدودیت نرخ یا خطای موقت | کد خطا و Retry-After | ارسال را کنترل و با تأخیر دوباره تلاش کنید |
کدهای HTTP و نام خطا در Web Push مستقیم و FCM لزوماً یکسان نیستند. پاککردن همه دادههای مرورگر اولین قدم عیبیابی نیست؛ ممکن است اشتراک و وضعیت ورود کاربر را از بین ببرد. ابتدا خطا، مبدأ، نسخه worker و نوع پیام را ثبت کنید و مشکل را با یک اشتراک آزمایشی بازتولید کنید.
راهاندازی و نگهداری در پوشفا
از راهنمای شروع و مستندات SDK وب استفاده کنید. سرویس بسازید، اسکریپت و فایل worker همان سرویس را نصب کنید و با یک دستگاه واقعی عضو شوید. در سایتی که قبلاً PWA دارد، ثبت worker جدید را با ساختار موجود هماهنگ کنید. تغییر پروژه Firebase یا کلیدهای اشتراک میتواند به مهاجرت توکنها نیاز داشته باشد؛ آن را مانند یک تغییر صرفاً ظاهری انجام ندهید.
- ثبت و دریافت روی صفحه باز، صفحه پسزمینه و پس از بستن صفحه بررسی شود.
- حالت مجوز مسدود، شبکه قطع، اشتراک نامعتبر و تصویر ناموجود بررسی شود.
- کلیک متن و دکمهها به مقصد صحیح برسد و گزارش با تنظیمات فعالشده تطبیق داشته باشد.
- شناسه سرویس، پیام و تلاش ارسال در لاگ قابل جستوجو باشند؛ توکن کامل و کلید خصوصی ثبت نشوند.
- نرخ خطا به تفکیک مرورگر و نسخه SDK رصد شود تا افت یک پلتفرم در میانگین کل پنهان نماند.
پرسشهای متداول
آیا بستهبودن صفحه مانع دریافت است؟
وب پوش به بازبودن همان صفحه وابسته نیست، اما رفتار مرورگر، وضعیت اجرای آن، اتصال و تنظیمات سیستم روی دریافت اثر میگذارد. این قابلیت را روی دستگاههای واقعی مخاطبان بررسی کنید.
آیا میتوان بدون اجازه پیام فرستاد؟
خیر؛ داشتن endpoint یا توکن جای رضایت معتبر کاربر را نمیگیرد. مسیر لغو عضویت و درخواست دوباره نیز باید انتخاب کاربر را رعایت کند.
آیا وب پوش برای کار پسزمینه بیصدا مناسب است؟
آن را ابزار عمومی اجرای کار بیصدا فرض نکنید. الزامات نمایش به مرورگر وابسته است و خصوصاً در WebKit باید رفتار قابل مشاهده رعایت شود. خاموشکردن نمایش بدون توجه به پلتفرم میتواند به اشتراک آسیب بزند.
برای جزئیات فنی به مستندات Push API، ثبت اشتراک و اعتبار پیام در FCM مراجعه کنید.