برمجة الأندرويد

FCM بالعربية – Firebase Cloud Messaging الجزء الثانى

فى الدرس السابق FCM بالعربية Firebase Cloud Messaging الجزء الأول تحدثنا عن كيفية إنشاء تطبيق فى الـ Console الخاص بالـ Firebase وكذلك قمنا بعمل Implementation من جانب الاندرويد حيث أنشأنا Listener للإستماع لرسائل الـ Firebase وإظهار الـ Notification وجربنا ارسال Notification من الـكونسول الخاص بالـ Firebase وتم الامر بنجاح وتم استقبال الاشعار  وكل شىء يعمل بشكل جيد واليوم سنكمل مشوارنا مع FCM وكما كنا نفعل فى GCM بإنشاء كلاس خاص بتولى أمر تحديث الـ Token ونقوم بعمل implement لـ onRefreshToken حيث كما ذكرنا سابقنا أن الـ token الخاص بالتطبيق على الجهاز قد يتم تحديثه لانتهاء مدته أو لأسباب أمنية لذلك سنفعل هذا الامر ايضا مع FCM وسننشىء كلاس تتولى أمر تحديث التوكن اضافة الى ذلك لم نقم بعمل Service تتولى أمر ارسال الـ Token الى السيرفر الخاص بنا فى الدرس السابق حيث نحتاج لهذه الخطوة ايضا وتنفيذ هذه الكلاسات سنقوم به اليوم اضافة الى جانب السيرفر  .

 

ملخص سريع لما نفعله بشكل عام فى FCM لترتب افكارك   :

لإضافة أو استخدام FCM نقوم  بعمل تطبيق فى Firebase Console او استخدام تطبيق سابق ثم تحميل ملف google-services.json واضافته للمشروع مع تهيئة ملفات الـ gradle بعد ذلك نبدأ  بكتابة الكود فى جزئين جزء الأندرويد وجزء السيرفر

جزء الأندرويد

– نقوم بإنشاء كلاس يعمل كـ Service لجلب الـ token وإرساله الى قاعدة البيانات فى السيرفر الخاص بنا حتى اذا ما اردنا ارسال اشعارات لاحقا برمجيا نقوم باستخدام هذه الـ tokens .

– نقوم بإنشاء كلاس يعمل كــ Service للإستماع او مراقبة تحديث الـ Token حتى اذا ما تم تحديث الـ Token نقوم بارساله الى السيرفر الخاص بنا مرة اخرى حيث يصبح التوكن القديم منتهى ولن تصل الاشعارات لصاحب الجهاز .

– نقوم بإنشاء كلاس يعمل كـ Listener لمراقبة الرسائل القادمة من Firebase وإظهار النوتيفيكشن او اتخاذ اى اجراء اخر عند وصول رسالة من الـ Firebase.

 

جزء السيرفر

– نقوم بكتابة كلاس نتصل به من خلال الاندرويد ونمرر له الـ token ليخزنه فى قاعدة البيانات الخاصة بنا على السيرفر لنستخدم الـ tokens لاحقا فى ارسال الاشعارات برمجيا .

– نقوم بكتابة  كلاس او كود إرسال الاشعارات ليتم إرسالها سواء عند اضافة موضوعات جديدة أو عند حدوث حدث معين او انشاء ملفات ترسل اشعار عند منادتها من التطبيق او اى طريقة اخرى حسب التطبيق الموجود عندك ويمكن ان يتم ذلك بوسائل اخرى غير php كـ Asp.net او node.js او غيرها لكننا هنا نقوم باستخدام الـ php دائما لبرمجة الأشياء المتعلقة بالسيرفر

 

والان لنتابع ..

فى الدرس السابق بدأنا بجزء الاندرويد وأنشأنا كلاس يعمل كـ Listener للـ FCM يستمع الى Firebase ويقوم بتنفيذ اكشن معين عند وصول اشعار والذى يكون على الاغلب اظهار نوتيفيكشن للمستخدم .

والان سنقوم بإنشاء كلاس يعمل كـ Service لـجلب الـ token وإرساله الى السيرفر الخاص بنا  وسنطلق عليه اسم FCMRegistrationService

public class FCMRegistrationService extends IntentService {

    public FCMRegistrationService(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

    }
}

 

الان ننتقل للاستضافة او السيرفر الخاص بنا لتجهيز قاعدة البيانات وسأقتبس هذا الجزء من التدوينة السابقة  الخاصة بـ GCM حيث اننا سنفعل نفس الامر .

1.FCMRegistrationService

 

الان عندما تبدأ هذه السيرفس بالعمل سنحصل على الـ token وسيكون مخزن فى المتغير String token و يجب علينا عمل امرين

الاول :  ارسال هذا التوكن الى السيرفر الخاص بنا وتسجيله فى قاعدة البيانات حتى نستخدمه لاحقا عند ارسال النوتيفيكشنز

والثانى :  هو  تخزين قيمة فى الـ SharedPreference بأننا حصلنا على token وبالتالى عند فتح التطبيق كل مرة نقوم بفحص ذلك وبالتالى اذا تم الحصول على توكن وارساله من قبل فلا حاجه لارسال التوكن للسيرفر  مرة أخرى حيث يكون التوكن الخاص بهذا الجهاز مخزن فى السيرفر الخاص بنا أون لاين ويمكن ارسال الـ Notification له بكل سهولة عبر GCM  .

سوف اقوم بالذهاب الى الـ phpmyadmin وإنشاء جدول جديد اسمه users_token  بداخله عمود id وعمود tokens

الان سنقوم بإنشاء ملف php لادخال القيم الى الجدول يتم الاتصال به مباشرة بعد الحصول على الـ token من الـموبايل وسأسميهaddnewtoken.php

سأستخدم كلاس Marei DB    فك الضغط وقم بتعديل بيانات الاتصال بقاعدة البيانات

ثم قم بملىء البيانات الخاصة بالسيرفر واسم المستخدم واسم قاعدة البيانات والباسورد ثم احفظها وارفعها للسيرفر

نقوم بإنشاء ملف addnewtoken.php

<?php
include 'DB.php';
$db = DB::getInstance();
$result = $db->insert('users_tokens',['tokens'=> $_POST['token'] ]);
if($result)
    echo 1;
else
    echo 0;

ما هذا ؟

السطر الاول : وسم فتح ملف الـ php وتعريف المستند

السطر الثانى : تضمين الكلاس DB لكى نستطيع استخدام الـ Methods منه ولمن ليس لديه خبره فى php  تشبه عندنا import فى الجافا

السطر الثالث : نستدعى الـميثود getInstance() والتى تعنى اننا انشأنا اوبجكت جديد من الكلاس وقمنا بامساكه بالمتغير $db  .

السطر الرابع : قمنا باستخدام الميثود insert الموجوده بكلاس الـ DB واعطينها بارامترين الاول هو عباره عن اسم الجدول users_tokens والثانى هو عباره عن اسم العمود والقيمة على هيئة php array حيث tokens اسم العمود و $_POST[‘tokens’] هى القيمة التى سنرسلها لهذا الملف بالطريقة POST واسمها token

السطر الخامس وحتى الاخير نقوم بتفحص هل تم الإدخال بنجاح أم لا اذا تم اضافة الـتوكن سوف يتم طباعة 1 واذا حدث مشكلة سوف يتم طباعة 0

وسنقوم الان بكتابة ميثود سوف ترسل الـ token من الأندرويد بعد الحصول عليه وسأستخدم مكتبة Volley والتى تم  شرحها فى هذه التدوينة من سلسلة Android WebService بالعربية

سأقوم بإنشاء ميثود اسمها sendTokenToServer داخل كلاس الـ FCMRegistrationService

    private void sendTokenToServer(final String token) {
        String ADD_TOKEN_URL = "http://developerhendy.16mb.com/addnewtoken.php";
        StringRequest request = new StringRequest(Request.Method.POST, ADD_TOKEN_URL, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                int responseCode = Integer.parseInt(response);
                if (responseCode == 1) {
                    prefEditor.putBoolean("token_sent", true).apply();
                    Log.e("Registration Service", "Response : Send Token Success");

                } else {
                    prefEditor.putBoolean("token_sent", false).apply();
                    Log.e("Registration Service", "Response : Send Token Failed");


                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                prefEditor.putBoolean("token_sent", false).apply();
                Log.e("Registration Service", "Error :Send Token Failed");

            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("token", token);
                return params;

            }
        };

        Volley.newRequestQueue(this).add(request);

    }

وهذه الميثود تقوم بكل بساطة بأخذ الـ token وإرساله الى السيرفر وذلك باستخدام Volley  يمكنك استخدام HttpUrlConnection او Retrofit او اى مكتبة اخرى ان اردت  وتقوم بحفظ حالة ارسال التوكن فى الشيرد بريفرنسس لكى نقوم بتفحص الكود لاحقا اذا لم يكن تم الارسال فيتم تشغيل السيرفس مرة اخرى لجلب توكن وارساله الى السيرفر .

 

 

وتصبح السيرفس بالكامل كالتالى :

public class FCMRegistrationService extends IntentService {
    SharedPreferences preferences;

    public FCMRegistrationService() {
        super("FCM");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String token = FirebaseInstanceId.getInstance().getToken();
        preferences = PreferenceManager.getDefaultSharedPreferences(this);
        if (!preferences.getBoolean("token_sent", false))
            sendTokenToServer(token);

    }

    private void sendTokenToServer(final String token) {
        String ADD_TOKEN_URL = "http://developerhendy.16mb.com/addnewtoken.php";
        StringRequest request = new StringRequest(Request.Method.POST, ADD_TOKEN_URL, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                int responseCode = Integer.parseInt(response);
                if (responseCode == 1) {
                    preferences.edit().putBoolean("token_sent", true).apply();
                    Log.e("Registration Service", "Response : Send Token Success");

                } else {
                    preferences.edit().putBoolean("token_sent", false).apply();
                    Log.e("Registration Service", "Response : Send Token Failed");


                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                preferences.edit().putBoolean("token_sent", false).apply();
                Log.e("Registration Service", "Error :Send Token Failed");

            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("token", token);
                return params;

            }
        };

        Volley.newRequestQueue(this).add(request);

    }

}

 

الان انتهينا من تنفيذ الكلاس التى ستقوم بالحصول على  الـ Token وإرساله  الى السيرفر الخاص بنا

 

سننتقل الى كلاس مراقبة تحديث الـ Token وسنطلق عليه اسم FCMTokenRefreshListenerService او اى اسم تحبه .

 

2.FCMTokenRefreshListenerService

وبداخلها سنقوم بفتح الكلاس السابقة عن طريق intent لكن سنعطيه علامة من خلال الـ intent ان التوكن تم تحديثه لذلك يقوم بتغيير حالة الـ token من تم ارساله الى لم يتم ارساله وبالتالى يقوم بارسال التوكن الجديد .

public class FCMTokenRefreshListenerService extends FirebaseInstanceIdService {
    @Override
    public void onTokenRefresh() {

        Intent intent = new Intent(this, FCMRegistrationService.class);
        intent.putExtra("refreshed", true);
        startService(intent);
    }
}

 

ونقوم بتعديل الكلاس السابقة FCMRegistrationService لجعلها تستقبل نتيجة الـ intent  لتصبح كالتالى

 

package com.hendiware.hellofirebase;

import android.app.IntentService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.firebase.iid.FirebaseInstanceId;

import java.util.HashMap;
import java.util.Map;

public class FCMRegistrationService extends IntentService {
    SharedPreferences preferences;

    public FCMRegistrationService() {
        super("FCM");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // get Default Shard Preferences   
        preferences = PreferenceManager.getDefaultSharedPreferences(this);
        
        // get token from Firebase 
        String token = FirebaseInstanceId.getInstance().getToken();

        // check if intent is null or not if it isn't null we will ger refreshed value and 
        // if its true we will override token_sent value to false and apply 
        if (intent.getExtras() != null) {
            boolean refreshed = intent.getExtras().getBoolean("refreshed");
            if (refreshed) preferences.edit().putBoolean("token_sent", false).apply();
        }
        
        // if token_sent value is false then use method sendTokenToServer to send token to server 
        if (!preferences.getBoolean("token_sent", false))
            sendTokenToServer(token);

    }
    
    
    // method use volley to send token to server and stop the service when done or error happened 
    private void sendTokenToServer(final String token) {
        String ADD_TOKEN_URL = "http://developerhendy.16mb.com/addnewtoken.php";
        StringRequest request = new StringRequest(Request.Method.POST, ADD_TOKEN_URL, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                int responseCode = Integer.parseInt(response);
                if (responseCode == 1) {
                    preferences.edit().putBoolean("token_sent", true).apply();
                    Log.e("Registration Service", "Response : Send Token Success");
                    stopSelf();

                } else {
                    preferences.edit().putBoolean("token_sent", false).apply();
                    Log.e("Registration Service", "Response : Send Token Failed");
                    stopSelf();


                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                preferences.edit().putBoolean("token_sent", false).apply();
                Log.e("Registration Service", "Error :Send Token Failed");
                stopSelf();

            }
        }) {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("token", token);
                return params;

            }
        };

        Volley.newRequestQueue(this).add(request);

    }

}

 

 

الان يتبقى فقط أن نضيف هذه الكلاسات فى ملف Manifest لانه اذا لم نقم باضافتها فلن تعمل بالتاكيد 😀

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hendiware.hellofirebase">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!--###  listener service listen to firebase messages ###-->
        <service
            android:name=".MyFCMService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

        <!--###  Register service get token and send it to service  ###-->
        <service android:name=".FCMRegistrationService" />

        <!--###  Service response to token refresh event  ###-->
        <service
            android:name=".FCMTokenRefreshListenerService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>
    </application>

</manifest>

 

3.MyFCMService

وسنقوم بتعديل كلاس الدرس السابق لسحب البيانات من ال data ليناسب ما سنفعله فى السيرفر

public class MyFCMService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        
        String title = remoteMessage.getData().get("title");
        String message = remoteMessage.getData().get("message");
 
        sendNotification(remoteMessage.getData().get("title"), remoteMessage.getData().get("message"));

    }

    private void sendNotification(String title, String messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle(title)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
}

الان انتهينا من جزء الأندرويد لقد أنشأنا 3 كلاسات كلاس عباره عن سيرفس يحصل على التوكن ويرسله للسيرفر ، كلاس يقوم بمراقبة التوكن فى حالة التحديث ، كلاس مراقبة واستماع رسائل firebase واتخاذ اجراء عند وصول الرسالة .

وسننتقل الى جزء السيرفر المتبقى

 

Server Side: Send Notification 

لقد سبق وأنشانا ملف اضافة التوكن الى الداتا بيز والذى يتواصل معه كلاس ارسال التوكن  لكن الان نريد تنفيذ ارسال الاشعارات برمجيا من جهة السيرفر الخاص بنا وكما فعلنا من قبل فى GCM باستخدام curl والذى يسمح لك بعمل http request  من داخل ملف php  مباشرة سنفعل هذا هنا واذا كنت لا تعرف ما هو الـ http request بشكل عام راجع تدوينة  ما يجب أن يعرفه كل مبرمج عن الـ Http

الـ http request نرسله الى firebase مرفق معه الـ apikey  الخاص بالمشروع الموجود على firebase  بالاضافة الى محتوى رسالة الاشعار وبالتأكيد التوكنز التى سيتم الارسال اليها والكود التالى يقوم بذلك  :

<?php
include 'DB.php';
$db = DB::getInstance();
$tokens = $db->table('users_tokens')->select('tokens')->get();

$tokens_arr = [];
foreach ($tokens as $key => $token) {
    array_push($tokens_arr, $token['tokens']);
}

    //************   rplace this with your key values data or modifi it as you like ***************// 
 $data = array('title' => 'Hendiware!','message' => 'are you ready to learn something new today ?');

 sendMessageThroughFCM($tokens_arr, $data);
 

function sendMessageThroughFCM($registatoin_ids, $data)
{
    $url = 'https://fcm.googleapis.com/fcm/send';
    $fields = array(
        'registration_ids' =>   $registatoin_ids   ,
        'data' => $data,
    );
    //************   rplace this with your api key ***************// 
    define("GOOGLE_API_KEY", "AIzaSyDnMUM8SWm0MhV1a4NaWsptue8HVZcf4Zk");
    $headers = array(
        'Authorization: key=' . GOOGLE_API_KEY,
        'Content-Type: application/json'
    );
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
    $result = curl_exec($ch);
    if ($result === FALSE) {
        die('Curl failed: ' . curl_error($ch));
    }
    curl_close($ch);
    echo $result;

 }

ما هذا ؟ 

السطر 1 وسم فتح ملف php

السطر 2 تضمين ملف DB.php وهو ملف كلاس Marei DB 

السطر 3 إنشاء اوبجكت أو Instance من ملف قاعدة البيانات وإمساكه بالمتغير $db  .

السطر 4 تحديد الـ tokens من الجدول الخاص بالـ user_tokens فى قاعدة البيانات .

السطر 6 إنشاء array اسمها tokens_arr ليتم تخزين الـ tokens بها  بشكل تسلسلى .

السطر 7-9 نقوم بعمل loop على نتيجة التحديد ونقوم بتخزين الـ tokens فى الـ array الجديدة .

السطر 10 عبارة عن مصفوفة الـ data التى سترسل الى الأندرويد عبر سيرفر FCM يمكنك وضع اى قيم تريدها على هيئة key – values  واستقبالها من الطرف الاخر فى كلاس MyFCMService كالتالى :

حيث استقبلنا هنا القيمة title والقيمة message ولو كانت هناك قيمة hendiware ضمن الـ data لاستقبلناها ايضا !

 

السطر 12  sendMessageThroughFCM($tokens_arr, $data); استدعينا الميثود sendMessageThroughFCM واعطيناها باراميتر الاول الـ array الخاصة بالـ tokens والباراميتر الثانى هو الـ data وهى عباره عن array ايضا على هيئة keys و values .

 

السطر 15-42 محتوى الميثود sendMessageThroughFCM نقوم فيها باستخدام curl فى عمل http request للرابط الخاص بالارسال عبر FCM نرفق الـ API Key الخاص بالسيرفر من جوجل  والذى يمكننا جلبه من console الـ firebase عن طريق الضغط على التطبيق واختيار Manage  ثم CloudMessaging كالتالى

اضافة الى ذلك نرفق ايضا array من الـ tokens وكذلك الـ data التى سيتم ارسالها الى الموبايل ويمكنك الرجوع الى تدوينة GCM بالـعربية – الدرس الثانى لمعرفة تفاصيل اكثر حول كود curl الموجود فى الكود السابق .

 

الان انتهينا من ملف php يمكنك رفعه الى السيرفر واستدعاؤه ستجد أنه تم ارسال النوتيفيكشن برمجيا بنجاح 😀

 

اذا لم يسر الامر معك بنجاح فتأكد بانه حدث شىء خاطىء اثناء تطبيقك  :/ راجع خطواتك أكثر من مرة هذا الدرس والدرس السابق  وتتبع الخطوات مرة أخرى بتركيز  وتأكد ان كل شىء تم كتابته بشكل صحيح وسيعمل .

 

ملحوظة :

  • فى الاستخدام الفعلى للـ FCM فى تطبيقك يكون هناك حدود على ارسال النوتيفيكشن لـ 1000 توكن فى المرة الواحدة لذلك يجب عليك عمل loop من خلال php وارسال التوكنز الموجودة عندك 1000 فى كل لفة حتى ينتهى الارسال لكل المستخدمين اى فى المثال السابق الـ array ستكون 1000 عنصر فقط كل مرة ويتم مناداة sendMessageThroughFCM كل لفة  .
  • ملف php السابق مجرد مثال وبالتأكيد لا احد يقوم استخدامه بهذه الطريقة سوف تستخدمه حسب الحالة الموجودة لديك مثلا تريد ارسال اشعار عند وجود مواضيع جديدة ستستخدم محتوى الملف السابق ليتم تنفيذه عند اضافة مواضيع جديدة فقط وهكذا .

 

المشروع على Github 

 

السابق
FCM بالعربية – Firebase Cloud Messaging الجزء الأول
التالي
درس Firebase Authentication

18 تعليق

أضف تعليقا

  1. محمد قال:

    فـــخــــم

  2. وفقك الله ومشاء الله ولا اروع

  3. محمد قال:

    مجهوود رائع جدااا
    طلب بسيط لو سمحت
    في خطوة [ Server Side: Send Notification ]
    لم نستخدم لغة php
    بل استخدمنا لغة C# مع PushSharp 4.0.10
    للأسف لم اتمكن من استقبال الـ Notification
    هل من مسااعدة 🙂

    1. Hendiware قال:

      مرحبا محمد ممكن تورينى الكود .

      1. محمد قال:

        مشكور علي الرد
        وضعت الكود علي موقع pastebin.com
        الرابط // http://pastebin.com/Dpi7Fnmi

        مشكور مقدماً ..

  4. محمد قال:

    مرحبا يا استاذ …
    حابب اخبرك اني الحمد لله حليت المشكلة
    كانت المشكلة في رقم الـ API key

    مشكور جدا علي الرد
    اسف اذا كنت غلبتك
    ننتظر المواضيع القادمة علي احر من الجمر
    بارك الله فيكم

    1. Hendiware قال:

      جميل انه تم حل المشكلة .
      بالتوفيق يامحمد .

  5. Mohamed قال:

    الله ينور 😀
    بس فى مشكله ف ال notification مهما بعمله customization من حيث ال icon او ال Title ما شابه بتفضل ال default !
    و شكرا على الدروس الممتازه فعلا 😀

    1. Hendiware قال:

      مرحبا محمد ،
      بالنسبة لل customization يتم من خلال ميثود sendNotification فى الأندرويد وجرب عمل clean project ثم جرب تشغيل التطبيق والاشعارات .

  6. Ilyas قال:

    السلام عليكم

    لماذا نقوم بمراقبة تحديث Token الجهاز و نقوم بارساله الى السيرفر ؟
    اظن انه ليس ضروريا, لان في جميع الاحوال ال Notification سوف ترسل الى جميع الاجهزة الي يوجد فيها التطبيق
    اذا لماذا !!

  7. أحمد شاهين قال:

    السلام عليكم ورحمة الله وبركاته
    جزاك الله عنا خير الجزاءكنت عاوز أسأل على حاجة ، دلوقتى لو المستخدم عمل Sign Out وبعدين مستخدم آخر استخدم نفس الموبايل فى انه يعمل Sign In وقتها الموبايل هايستقبل تنبيهات المستخدم الاول ومش هايستخدم تنبيهات المستخدم الثاني ؟؟
    ممكن احل المشكلة دى ازاى ، انا فكرت ان اخلي معتمدة على ID المستخدم مش ID الموبايل وفى كل مرة يحصل Sign In من أى موبايل ، الموبايل يبعت ID المستخدم وكمان ID الموبايل واستخدم ID الموبايل فى إنى أرسل للمستخدم التنبيهات الخاصة بيه ….
    حاسس انه حل معقد ، وكنت عاوز رأيك بعد إذنك؟؟

  8. Tag قال:

    السلام عليكم

    ايه وظيفة
    stopSelf();
    اللي موجودة في الكود

  9. mery قال:

    مرحبا استاذ
    كيف لم اليورز يضغط على Notification افتح new activity بباقى التفاصيل ؟؟

  10. Ayman khaled قال:

    انا عاوز لما اضغط على زراز ابعت notifiction لكل tokens اللى فى DB لو وضعت السطر startService(new Intent(this,FCMRegistrationService.class));
    داخل action للزرار هىبعت notifiction؟؟؟؟

  11. norhan قال:

    كيف انشأ php code in firebase server

  12. اسأل الله ان يجزيك كل ما هو خير انشالله ( الى موضوعك هذا انهي بحثي عن هذا الموضوع لأكتفائي من الاجابة على الأسئلة الي في بالي ) شكراً من كل قلبي.

  13. Fatimah قال:

    I’ve gotten 2 errors when clone from GitHub
    because of HelloFireBase.iml file & app.iml file
    how can I fix it ?

  14. Ahmed Naser قال:

    ازاي استخدم https في volley

اترك تعليقاً

This site uses Akismet to reduce spam. Learn how your comment data is processed.