Android Volley仅运行一次,仅显示一个通知-使用PHP / Volley的Firebase云消息传递

问题描述 投票:-2回答:1

我正在使用Firebase开发一个Android聊天应用。除推送通知外,其他一切正常。我已经在Google上搜索并阅读了有关该问题的几乎所有帖子,但仍然没有找到解决方案!

问题:将应用重新安装到设备上!我收到通知(仅一次),然后,没有任何显示的通知。 Volley返回一条成功消息“每条成功消息的多播ID都相同,甚至每条成功消息的消息ID都相同”,想知道这与问题有关!请看下面的代码:

1)我的Web地址(应用服务器)上运行的我的PHP脚本:

<?php

     define( 'API_ACCESS_KEY', 'AAAAeaFcZdA:APA91bFqhLc..............' );
     $token = $_GET["token"];

     $title = $_POST["title"];
     $notification = $_POST["message"];
     $msg =
     [
        'message'   => $notification,
        'title'   => $title,

     ];
     $fields = 
     [
        'to'  => $token,
        'data'      => $msg
     ];

     $headers = 
     [
       'Authorization: key=' . API_ACCESS_KEY,
       'Content-Type: application/json'
     ];
     $ch = curl_init();
     curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' );
     curl_setopt( $ch,CURLOPT_POST, true );
     curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
     curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
     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;
    ?>

2)我的MessagingService(Firebase)获取通知,因为我收到第一个通知,所以我相信它的配置正确!

public class MessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Timber.i("From: " + remoteMessage.getFrom());
        //Check if message contains a data payload.
        if (remoteMessage.getData().size() > 0) {
            Timber.i("Message data payload: " + remoteMessage.getData());
            Map<String, String> data = remoteMessage.getData();
            sendNotification(data);
        }
        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Timber.i("Message Notification Body: " + remoteMessage.getNotification().getBody());
            Map<String, String> data = remoteMessage.getData();
            sendNotification(data);
        }
        Map<String, String> data = remoteMessage.getData();
        sendNotification(data);

    }

    @Override
    public void onNewToken(@NonNull String token) {
        Timber.i("MyToken:    " + token);
        sendRegistrationToServer(token);
    }

    private void sendRegistrationToServer(String token) {
        // TODO: Implement this method to send token to your app server.

        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference usersdRef = database.getReference("users");
        FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
        if (user != null) {
            usersdRef.child(user.getUid()).child("tokens").setValue(token);
        }
    }


    private void sendNotification(Map<String, String> messageBody) {

        String myTitle = messageBody.get("title");
        final int not_nu = generateRandom();
        Intent intent = new Intent(this, ChatMessageActivity.class);
        intent.putExtra("username", myTitle);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        ChatUserModel.chatWith = myTitle;
        PendingIntent pendingIntent = PendingIntent.getActivity(this, not_nu /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        String channelId = getString(R.string.notification_channel_id);
        Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.marker)
                        .setContentTitle(messageBody.get("title"))
                        .setContentText(messageBody.get("message"))
                        .setAutoCancel(true)
                        .setSound(defaultSoundUri)
                        .setContentIntent(pendingIntent);

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

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }

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

    public int generateRandom() {
        Random random = new Random();
        return random.nextInt(9999 - 1000) + 1000;
    }}

3)我将消息发送给其他用户的聊天活动。getOtherToken =我将向其发送消息的其他用户令牌ID

sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String messageText = messageArea.getText().toString();

                SimpleDateFormat sdf = new SimpleDateFormat("dd.MMM.yyyy", Locale.getDefault());
                String currentDate = sdf.format(new Date());
                String currentTime = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());

                if (!messageText.equals("")) {
                    Map<String, String> map = new HashMap<String, String>();
                    map.put("message", messageText);
                    map.put("user", user.getDisplayName());
                    map.put("timetoshow", currentTime);
                    map.put("dateStamp", currentDate);
                    usersmRef.child(reference1).push().setValue(map);
                    usersmRef.child(reference2).push().setValue(map);
                    messageArea.setText("");
                    sendNotificationToappServer(getOtherToken, user.getDisplayName(), messageText);
                    Timber.i("GetOtherTOken: " + user.getDisplayName() + " | " + getOtherToken + " | " + messageText);
                }


            }
        });

4)与上述相同的ChatActivity.java中的我的Volley方法,其中我向我的App Server发送字符串请求,这里的令牌是将接收消息的用户的令牌!

    public void sendNotificationToappServer(String token, String title, String notification) {
        String SERVER_ADDRESS = "https://www.mywebsite/notification.php?token=";

        RequestQueue requestQueue;

        // Instantiate the cache
        Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap

        // Set up the network to use HttpURLConnection as the HTTP client.
        Network network = new BasicNetwork(new HurlStack());

        // Instantiate the RequestQueue with the cache and network.
        requestQueue = new RequestQueue(cache, network);

        // Start the queue
        requestQueue.start();


        StringRequest stringRequest = new StringRequest(Request.Method.POST, SERVER_ADDRESS + token,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Toast.makeText(ChatMessageActivity.this, response, Toast.LENGTH_LONG).show();
                        Timber.i("Volley: %s", response.toString());
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(ChatMessageActivity.this, error.toString(), Toast.LENGTH_LONG).show();
                        Timber.i("Volley Error: " + error.toString());
                    }
                }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<String, String>();
                params.put("title", title);
                params.put("message", notification);
                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                params.put("Content-Type", "application/x-www-form-urlencoded");
                return params;
            }
        };

        requestQueue.add(stringRequest);
    }

5)我的Volley Response在Android Studio中录制成功,这是第一次,它首次提供了推送通知,但此后直到重新安装为止!“凌空反应”

除上述以外的任何要求!请告诉我。手指交叉!

android firebase firebase-cloud-messaging android-volley
1个回答
0
投票

我能够解决此问题!好吧,我发现问题是由于凌空造成的缓存管理。在发布新的队列请求之前,清除缓存将解决此问题!queue.getCache().clear();

[此外,我更喜欢在Volley中使用单例类。这是上面sendNotificationToappServer方法的更新代码:

    public void sendNotificationToappServer(String token, String title, String notification) {
        String SERVER_ADDRESS = "https://www.mywebsite/notification.php?token=";

//         Get a RequestQueue
                RequestQueue queue = MySingleton.getInstance(ChatMessageActivity.this).
                 getRequestQueue();

        StringRequest stringRequest = new StringRequest(Request.Method.POST, SERVER_ADDRESS + token,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Toast.makeText(ChatMessageActivity.this, response, Toast.LENGTH_LONG).show();
                        Timber.i("Volley: %s", response.toString());
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(ChatMessageActivity.this, error.toString(), Toast.LENGTH_LONG).show();
                        Timber.i("Volley Error: " + error.toString());
                    }
                }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<String, String>();
                params.put("title", title);
                params.put("message", notification);
                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                params.put("Content-Type", "application/x-www-form-urlencoded");
                return params;
            }
        };

queue.getCache().clear();
        MySingleton.getInstance(getApplicationContext()).addToRequestQueue(stringRequest);
    }

上面问题中的PHP代码非常有效!因此,如果您正在寻找用于一对一消息传递的Firebase Cloud消息传递App服务器的PHP脚本,那就去吧!

© www.soinside.com 2019 - 2024. All rights reserved.