development

앱 시작시 이상한 푸시 메시지 수신

big-blog 2021. 1. 8. 22:46
반응형

앱 시작시 이상한 푸시 메시지 수신


내 푸시 서비스에서 캡처 한 이상한 푸시 메시지가 나타납니다.

Bundle[{CMD=RST_FULL, from=google.com/iid, android.support.content.wakelockid=1}]

어제 막 일어나기 시작했고 어떤 코드 변경이 이것에 대한 책임이 있는지 알 수 없습니다. 이 메시지를 전에 본 사람이 있고 그 메시지가 어디에서 왔으며 그 이유를 알고 있습니까?


앱에 백업에서 복원 된 데이터가 있기 때문에이 메시지가 표시됩니다. 백업에 등록 토큰이 포함되었을 수 있으므로이 브로드 캐스트는 백업 된 토큰이 작동하지 않으므로 새 토큰을 가져 오도록 앱에 알리는 메시지가 전송됩니다.

이는 새로운 GCM API를 위한 것이며 InstanceIdListenerService 구현의 onTokenRefresh () 메서드가 호출되어 앱이 모든 토큰을 다시 가져와야합니다.

불행히도 자신의 BroadcastReceiver를 작성하는 경우 이러한 메시지는 예상치 못한 메시지이며 앱이 중단 될 수 있습니다. 올바른 방법은 "보낸 사람"필드를 필터링하고 이러한 메시지 중 하나가 표시되면 토큰이 유효하지 않을 수 있으므로 GCM에 다시 등록하는 것입니다.

앱 데이터가 복원되는 새로 설치 한 상황이 아닌 경우 이러한 메시지가 표시되는 경우 android-gcm 메일 링리스트에 게시하세요 .


@morepork가 제안한대로 업데이트 된 GCM API 문서참조하십시오 .

WakefulBroadcastReceiver를 확장하는 기존 앱의 경우 GCMReceiver 및 GcmListenerService로 마이그레이션하는 것이 좋습니다. 마이그레이션하려면 :

앱 매니페스트에서 GcmBroadcastReceiver를 "com.google.android.gms.gcm.GcmReceiver"로 바꾸고 IntentService를 새 GcmListenerService로 확장하는 현재 서비스 선언을 바꿉니다.

클라이언트 코드에서 BroadcastReceiver 구현 제거

GcmListenerService를 사용하도록 현재 IntentService 서비스 구현을 리팩터링합니다.

자세한 내용은이 페이지의 예제 매니페스트 및 코드 샘플을 참조하세요.

자신의에서 샘플 코드 , 팔로우 꽤 간단합니다.

AndroidManifest.xml

<receiver
    android:exported="true"
    android:name="com.google.android.gms.gcm.GcmReceiver"
    android:permission="com.google.android.c2dm.permission.SEND">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
        <category android:name="com.example.client"/>
    </intent-filter>
</receiver>

<service
    android:name=".MyGcmListenerService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
    </intent-filter>
</service>

<service
    android:name=".MyInstanceIdListenerService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.android.gms.iid.InstanceID"/>
    </intent-filter>
</service>

<service
    android:name=".MyGcmRegistrationService"
    android:exported="false">
</service>

MyGcmListenerService.java

public class MyGcmListenerService extends GcmListenerService {
    @Override
    public void onMessageReceived(String from, Bundle data) {
        final String message = data.getString("message");
        makeNotification(message);
    }
}

MyGcmRegistrationService.java

public class MyGcmRegistrationService extends IntentService {
    private static final String TAG = "MyRegistrationService";
    private static final String GCM_SENDER_ID = "XXXXXXXXXXXX";
    private static final String[] TOPICS = {"global"};

    public MyGcmRegistrationService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        try {
            synchronized (TAG) {
                InstanceID instanceID = InstanceID.getInstance(this);
                String token = instanceID.getToken(GCM_SENDER_ID,
                        GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
                sendTokenToServer(token);
                subscribeTopics(token);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void subscribeTopics(String token) throws IOException {
        for (String topic : TOPICS) {
            GcmPubSub pubSub = GcmPubSub.getInstance(this);
            pubSub.subscribe(token, "/topics/" + topic, null);
        }
    }
}

MyInstanceIdListenerService.java

public class MyInstanceIdListenerService extends InstanceIDListenerService {
    public void onTokenRefresh() {
        Intent intent = new Intent(this, MyGcmRegistrationService.class);
        startService(intent);
    }
}

그런 다음 이전 등록 코드를

Intent intent = new Intent(this, MyGcmRegistrationService.class);
startService(intent);

I realized the same issue today. First, this message must come from google itself (from=google.com/iid), otherwise the from attribute would be the id of your project in google developer console (i.e. 475832179747). But to be sure, I shutdown our application server, and I still received the message.

I always receive it when I newly register at the Google Cloud Messaging server. It's not a big problem because you can filter the message by the intent-action, but I would really like to know the purpose of it.


For existing apps that extend a WakefulBroadcastReceiver, Google recommends migrating to GCMReceiver and GcmListenerService. To migrate:

  • In the app manifest, replace your GcmBroadcastReceiver with "com.google.android.gms.gcm.GcmReceiver", and replace the current service declaration that extends IntentService to the new GcmListenerService
  • Remove the BroadcastReceiver implementation from your client code
  • Refactor the current IntentService service implementation to use GcmListenerService For details, see the example manifest.

it seems google split the GCMIntentService which extended IntentService to handle gcms to two services, one extends GcmListenerService that will handle received messages and other that filter iid.InstanceID separately to filter out that notification received for first installation, this is from new gcm android guides

<service
    android:name="com.example.MyGcmListenerService"
    android:exported="false" >
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    </intent-filter>
</service>
<service
    android:name="com.example.MyInstanceIDListenerService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.android.gms.iid.InstanceID"/>
    </intent-filter>
</service>

https://developers.google.com/cloud-messaging/android/client


same thing is happening to me on at least an Asus tablet

likely on more devices but i haven't had a chance to take a look

i'm looking for some particular Strings in Intent.getExtras() so the fix was simple, if they aren't present then ignore the whole thing.

what are the chances someone from Google will show up and explain what's going on?


I had this problem during migrating GCM->FCM with receiving only wakelockid element from:

  • firebase console
  • reproduced request by postman with request like this:

{ "to": "<your token from FirebaseInstanceId.getInstance().getToken()>", "notification": { "body": "Hello", "title": "This is test message." } }

Also I copied also all code from google quickstart firebase messaging. Everything should be fine. However, after all tests I decided to double check my gradle libs versions. So I incremented them to the latest numbers. Since then I started receiving messages correctly.

The fastest solution I would recommend to download project from GitHub and try if this is working for You. Next step would be copy this code to Your project. If in one project everything is working fine, You have at least one standing/working point where to start.

There are rumors about android studio is causing this issue - but it is not true. I checked it.

It can be true that You could use the same old token (from gcm) and not receiving messages but If You had the same case like me which is migrating, then token should be refreshed to new one and You should handle it..

ReferenceURL : https://stackoverflow.com/questions/30479424/weird-push-message-received-on-app-start

반응형