Skip to content

Commit 879c84b

Browse files
authored
Call messageHandled after a message has been handled. (#5570)
* Called messageHandled() after a message has been handled to indicate that the message has been handled successfully.
1 parent a014114 commit 879c84b

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

firebase-messaging/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# Unreleased
2+
* [changed] Called messageHandled() after a message has been handled to indicate
3+
that the message has been handled successfully.
24
* [changed] Added an internal identifier to Firelog logging for compliance.
35

46
# 23.3.1

firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessagingService.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@
1515

1616
import static com.google.firebase.messaging.Constants.TAG;
1717

18+
import android.content.Context;
1819
import android.content.Intent;
1920
import android.os.Bundle;
2021
import android.text.TextUtils;
2122
import android.util.Log;
2223
import androidx.annotation.NonNull;
2324
import androidx.annotation.VisibleForTesting;
2425
import androidx.annotation.WorkerThread;
26+
import com.google.android.gms.cloudmessaging.CloudMessage;
27+
import com.google.android.gms.cloudmessaging.Rpc;
2528
import com.google.firebase.messaging.Constants.MessagePayloadKeys;
2629
import com.google.firebase.messaging.Constants.MessageTypes;
2730
import java.util.ArrayDeque;
@@ -82,6 +85,8 @@ public class FirebaseMessagingService extends EnhancedIntentService {
8285
private static final Queue<String> recentlyReceivedMessageIds =
8386
new ArrayDeque<>(RECENTLY_RECEIVED_MESSAGE_IDS_MAX_SIZE);
8487

88+
private Rpc rpc;
89+
8590
/**
8691
* Called when a message is received.
8792
*
@@ -173,6 +178,7 @@ private void handleMessageIntent(Intent intent) {
173178
if (!alreadyReceivedMessage(messageId)) {
174179
passMessageIntentToSdk(intent);
175180
}
181+
getRpc(this).messageHandled(new CloudMessage(intent));
176182
}
177183

178184
private void passMessageIntentToSdk(Intent intent) {
@@ -263,8 +269,20 @@ private String getMessageId(Intent intent) {
263269
return messageId;
264270
}
265271

272+
private Rpc getRpc(Context context) {
273+
if (rpc == null) {
274+
rpc = new Rpc(context.getApplicationContext());
275+
}
276+
return rpc;
277+
}
278+
266279
@VisibleForTesting
267280
static void resetForTesting() {
268281
recentlyReceivedMessageIds.clear();
269282
}
283+
284+
@VisibleForTesting
285+
void setRpcForTesting(Rpc rpc) {
286+
this.rpc = rpc;
287+
}
270288
}

firebase-messaging/src/test/java/com/google/firebase/messaging/FirebaseMessagingServiceRoboTest.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@
2626
import static org.mockito.ArgumentMatchers.anyString;
2727
import static org.mockito.ArgumentMatchers.argThat;
2828
import static org.mockito.ArgumentMatchers.eq;
29+
import static org.mockito.Mockito.doAnswer;
2930
import static org.mockito.Mockito.doReturn;
3031
import static org.mockito.Mockito.mock;
3132
import static org.mockito.Mockito.never;
3233
import static org.mockito.Mockito.spy;
3334
import static org.mockito.Mockito.times;
3435
import static org.mockito.Mockito.verify;
36+
import static org.mockito.Mockito.verifyNoMoreInteractions;
3537
import static org.robolectric.Shadows.shadowOf;
3638

3739
import android.app.Activity;
@@ -53,6 +55,8 @@
5355
import android.os.Process;
5456
import androidx.test.core.app.ActivityScenario;
5557
import androidx.test.core.app.ApplicationProvider;
58+
import com.google.android.gms.cloudmessaging.CloudMessage;
59+
import com.google.android.gms.cloudmessaging.Rpc;
5660
import com.google.common.collect.ImmutableSet;
5761
import com.google.common.collect.Sets;
5862
import com.google.firebase.FirebaseApp;
@@ -74,6 +78,7 @@
7478
import org.junit.Before;
7579
import org.junit.Test;
7680
import org.junit.runner.RunWith;
81+
import org.mockito.ArgumentCaptor;
7782
import org.mockito.ArgumentMatcher;
7883
import org.mockito.MockitoAnnotations;
7984
import org.robolectric.Robolectric;
@@ -211,6 +216,43 @@ public void testMessage_nullIntentExtras() throws Exception {
211216
assertThat(shadowOf(context).getNextStartedService()).isNull();
212217
}
213218

219+
@Test
220+
public void messageHandled() throws Exception {
221+
RemoteMessageBuilder builder =
222+
new RemoteMessageBuilder()
223+
.setFrom(DEFAULT_FROM)
224+
.setTo(DEFAULT_TO)
225+
.addData("key1", "value1")
226+
.setMessageId("message_id_456")
227+
.setSentTime(123456789);
228+
Intent intent = builder.buildIntent();
229+
Rpc mockRpc = mock(Rpc.class);
230+
service.setRpcForTesting(mockRpc);
231+
CountDownLatch latch = new CountDownLatch(1);
232+
doAnswer(
233+
invocation -> {
234+
latch.await();
235+
return null;
236+
})
237+
.when(service)
238+
.onMessageReceived(any(RemoteMessage.class));
239+
240+
shadowOf(context).clearStartedServices();
241+
sendBroadcastToReceiver(intent);
242+
processInternalStartService(context);
243+
244+
// Shouldn't call messageHandled while onMessageReceived is still running.
245+
verifyNoMoreInteractions(mockRpc);
246+
// Finish onMessageReceived, messageHandled should now be called.
247+
latch.countDown();
248+
flushTasks();
249+
ArgumentCaptor<CloudMessage> messageCaptor = ArgumentCaptor.forClass(CloudMessage.class);
250+
verify(mockRpc).messageHandled(messageCaptor.capture());
251+
CloudMessage message = messageCaptor.getValue();
252+
assertThat(message).isNotNull();
253+
assertThat(message.getIntent()).isEqualTo(intent);
254+
}
255+
214256
@Test
215257
public void testDuplicateMessageDropped() throws Exception {
216258
String messageId = "a.message.id";
@@ -308,6 +350,7 @@ public void testOnNewToken() throws Exception {
308350

309351
ServiceStarter.getInstance().startMessagingService(context, intent);
310352
processInternalStartService(context);
353+
flushTasks();
311354

312355
verify(service).onNewToken("token123");
313356
}
@@ -685,6 +728,7 @@ public void startServiceViaReceiver(Intent intent) throws InterruptedException {
685728
shadowOf(context).clearStartedServices();
686729
sendBroadcastToReceiver(intent);
687730
processInternalStartService(context);
731+
flushTasks();
688732
}
689733

690734
/**
@@ -700,7 +744,6 @@ public void processInternalStartService(Application application) throws Interrup
700744
assertEquals(application.getPackageName(), serviceIntent.getPackage());
701745

702746
service.onStartCommand(serviceIntent, 0 /* flags */, 1 /* startId */);
703-
flushTasks();
704747
}
705748

706749
// Flush the Service background tasks

0 commit comments

Comments
 (0)