FCM notifications not received when phone enters deep sleep - android

I have a problem with FCM functionality. When the phone is awake everything is working (notifications are received when the app is in foreground, background or even if the app is dead).
The problem starts when the phone is entering deep sleep.
As I remember wakelocks are not mandatory with FCM.
I'm pushing "data" type notification with "priority":"high" which should wake up the device.
Problem is that notifications will be received when the phone will awake.
public class FCMCallbackService extends FirebaseMessagingService {
private static final String TAG = "FCMCallbackService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Intent i = new Intent(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
}
public class FCMInitializationService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
...
}
}
In manifest:
<service android:name="gcmpush.FCMInitializationService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name="gcmpush.FCMCallbackService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
How can I wake application using push if the phone is sleeping? What is missing?
BDW - if I'm connected to WiFi and phone will go to sleep, but the application is not working - will it use WiFi to receive push? FCM can start the dead application. But if the app is dead, WiFi lock is not acquired. Can in such case device communicate with FCM Server?

The following message will not call your onMessageReceived() when your app is in the background or killed, and you can't customize your notification.
{
"to": "/topics/journal",
"notification": {
"title" : "title",
"text": "data!",
"icon": "ic_notification"
}
}
but instead using this will work
{
"to": "/topics/dev_journal",
"data": {
"text":"text",
"title":"",
"line1":"Journal",
"line2":"some data"
}
}
See ref link here

Related

Android Firebase background notification not firing

I'm developing an Android App that receives push notifications from Firebase.
I can get the token and send push notifications from Postman without any problem.
If the App is in foreground everything works as expected and I receive the payload in the onMessageReceived (I tested with various payloads).
But if I close the App it don't receive nothing. I tried with a lot of payloads, and I read all the documentation (diference between data and notification in payload).
Here's my classes that my project uses:
1 - The class that extends FirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "Android Push App";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
sendNotification("Received notification");
}
private void sendNotification(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.drawable.push_icon)
.setContentTitle("FCM Message")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
2 - The class that is responsible for get the token
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static String TAG = "Android Push App";
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token) {
Log.d(TAG, "Did obtained token");
Log.d(TAG, token);
}
3 - My Manifest:
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="FIREBASE_ACTIVITY" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name=".push.core.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service
android:name=".push.core.MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/push_icon" />
<meta-data android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/colorAccent" />
</application>
4 - The MainActivity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
Object value = getIntent().getExtras().get(key);
Log.d("MainActivity", "Key: " + key + " Value: " + value);
}
}
}
5 - Finally I tried this payload in the Postman
POST https://fcm.googleapis.com/fcm/send
Content-Type application/json
Authorization key=AIzaSy(...)kY
JSON Body (the examples I tried):
{
"to": "dxe0RDKbP...m9Uc","notification" : {
"body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "push_icon",
"sound" : "default"
}}
And:
{
"to": "dxe0RDKbP...m9Uc","notification" : {
"body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "push_icon",
"sound" : "default"
}}
And:
{
"to": "d3j-9OJ6R...C6w",
"notification" : {
"title": "title",
"body": "body"
},
"data": {
"tipo": "normal"
}}
Also added the "priority" key and it doesn't work.
What I'm I doing wrong?
Thanks for all the help you can gave to me :)
UPDATE
Now it's working.
There was a conflict between the FireBaseMessagingService and a Geofence Push that is running (fired by the App).
After removed this Geofence service everything works as expected.
Also use the notification and data keys in the payload of the push.
Thanks
Try this
you must not put JSON key 'notification' in your request to firebase API but instead use 'data'.
Example
use this
{
"to": "dxe0RDKbP...m9Uc",
"data": {
"body" : "great match!",
"title" : "Portugal vs. Denmark",
"icon" : "push_icon",
"sound" : "default"
}
}
EDIT
you can try with only body and title
{
"to": "dxe0RDKbP...m9Uc",
"data": {
"body" : "great match!",
"title" : "Portugal vs. Denmark"
}
}
Edit New
Add this in your manifest file android:stopWithTask="false" service property.
<service
android:name="com.yourapp.YourPushService"
android:stopWithTask="false"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
you need to remove notification payload from the json and add a data payload to it. This is because Android has an inbuilt functionality of taking care of notification when it sees notification payload, i.e., it, whenever notification payload is sent android directly sends it to system dray and onMessageReceived function, is not called.
As per the firebase documentation, Firebase notifications behave differently depending on the foreground/background state of the receiving app.
onMessageReceived is provided for most message types, with the following exceptions:
Notification messages delivered when your app is in the background. In this case, the notification is delivered to the device’s system tray. A user tap on a notification opens the app launcher by default.
Messages with both notification and data payload, both background and foreground. In this case, the notification is delivered to the device’s system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.
So you need to remove notification payload from your json and only need to keep data payload to trigger onMessageReceived when app is in background.
Link:https://firebase.google.com/docs/cloud-messaging/android/receive

How can I get the MobileFirst Foundation SDK to ignore Push Notifications sent by sources other than MobileFirst?

The MobileFirst Foundation SDK push notification receiver doesn't appear to be able to differentiate between notifications coming from MobileFirst and those from other sources.
We are trying to implement push notification in our app such that it can receive notifications from multiple sources. But what we've observed is that, while other cloud push providers' SDKs on process push notifications sources from that provider, the MobileFirst SDK processes all push notifications received by the device. This causes notifications sent from the cloud providers to be displayed twice on the device.
Some additional details:
This seems true regardless of the 3rd party cloud provider. We've tried 5 and all ignore MobileFirst notifications, however MobileFirst processes notifications from all of them.
GCM sender ID is the same for MobileFirst as for the other providers.
We are building native Android and iOS applications.
MobileFirst does not support this functionality out of the box, however because the other push services don't use the MobileFirst adapter used to send notifications via MobileFirst, the key is to add a property to the notification payload that can tell the device whether or not to show the notification.
So for instance, one solution would be to add a custom property in the adapter with the value "mfp" to the payload like this:
notification = WL.Server.createDefaultNotification(notificationText,
badgeDigit, {custom:"mfpush"});
Then in MyListener.java in the Android native code, add an "if" statement in the onReceive() function. This will handle the case when the application is running in the foreground:
public void onReceive(String props, String payload) {
JSONObject jsonObject;
JSONObject payloadJSON;
String notification = "";
String payloadNotif = "";
try {
// get payload from MFP adapter: custom property
payloadJSON = new JSONObject(payload);
payloadNotif = payloadJSON.getString("custom");
// if the payload "custom" property is "mfp", show the alert,
// if not, don't show the alert
if (payloadNotif.contains("mfp")) {
jsonObject = new JSONObject(props);
notification = jsonObject.getString("alert");
}else{
return;
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MainActivity.alertMsg("Notification", notification);
}
In the case where the application is running in the background, a new class needs to be created that extends com.worklight.wlclient.push.WLBroadcastReceiver and overrides the receive method. Create a CustomBroadcastReceiver class that extends WLBroadCastReceiver and overrides the onReceive method to call CustomGCMIntentService
public class CustomBroadcastReceiver extends WLBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
intent.setClassName(context,
CustomGCMIntentService.class.getName());
WakefulIntentService.sendWakefulWork(context, intent); } }
Then in CustomGCMIntentService, extend the MFP GCMIntentService class and override the two notify methods to check of the push came from MFP:
package com.sample.eventsourcenotificationsandroid.custom;
import android.content.Context;
import android.content.Intent;
import com.worklight.wlclient.push.GCMIntentService;
import org.json.JSONObject;
public class CustomGCMIntentService extends GCMIntentService {
#Override
public void notify(Context context, String tickerText) {
super.notify(context, tickerText);
}
#Override
public void notify(Context context, String alert, int badge, String
sound, Intent intent) {
if(isMobileFirstNotification(intent)) {
super.notify(context, alert, badge, sound, intent);
} }
#Override
public void notify(Context context, Message message, Intent intent) {
if(isMobileFirstNotification(intent)) {
super.notify(context, message, intent);
} }
private boolean isMobileFirstNotification(Intent intent) {
Message message = intent.getParcelableExtra("message");
JSONObject payload = message.getPayload();
return payload.optBoolean("mfpush", false);
} }
The way you're checking for notifications from MFP is by checking that the mfppush key as a value of true in the notification payload.
data: {
badge: "",
alert: "YourMessageContent",
sound: "your sound",
payload:{
mfpush: true
} }
Lastly, the manifest needs to be updated to use the new class instead of com.worklight.wlclient.push.WLBroadcastReceiver as follows:
<service android:name="com.worklight.wlclient.push.GCMIntentService" />
<receiver android:name="com.worklight.wlclient.push.WLBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<!-- removed intent-filter for com.google.android.c2dm.intent.RECEIVE
-->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.sample.eventsourcenotificationsandroid" />
</intent-filter>
</receiver>
<!-- start custom service and receiver -->
<service android:name="com.sample.eventsourcenotificationsandroid.custom.
CustomGCMIntentService" />
<receiver android:name="com.sample.eventsourcenotificationsandroid.custom.CustomB roadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.sample.eventsourcenotificationsandroid" />
</intent-filter>
</receiver>
<!-- end custom service and receiver -->

Android background notifications with Firebase Cloud Messaging not received

I've searched a lot about notifications when the app is in the background or closed. I'm using Firebase Cloud Messaging by the way. It won't work for me. I've used the Android setup and when the app is in the foreground or the phone is not locked the notification is received.
When installed the token is printed correctly and subscribed to the topic.
When I send a notification when the app is active in the foreground (so screen is unlocked and app is shown) I receive the notification and title as stated in the onMessageReceived.
When I send a notification when the app is not shown but is still in recent apps and screen is unlocked I receive the notification with title and message as stated in notification payload.
When I send a notification when the app is not shown but is still in recent apps and screen is locked nothing is received.
When I send a notification when app is *closed and removed from recent apps nothing is received.
How can I change this so the app will always receive the notifications, even when closed or the phone is locked?
Ps. I read about the Doze modus with protected apps, even when I put my app with the protected ones I receive nothing. I'm testing on a Huawei P8 Lite.
AndroidManifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<activity android:name=".activities.MainActivity"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".services.MyAppFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".services.FirebaseIDService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<receiver android:name=".services.NotificationReceiver" />
</application>
Gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.google.firebase:firebase-core:9.2.0'
compile 'com.google.firebase:firebase-messaging:9.2.0'
}
apply plugin: 'com.google.gms.google-services'
FirebaseMessagingService
public class MyAppFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
showNotification(getApplicationContext());
}
public static void showNotification(Context context){
Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("FCM Message")
.setContentText("FCM Body")
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setPriority(Notification.PRIORITY_MAX)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
FirebaseInstanceIDService
public class FirebaseIDService extends FirebaseInstanceIdService {
private static final String TAG = "FirebaseIDService";
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
System.out.println("Devicetoken: " + refreshedToken);
FirebaseMessaging.getInstance().subscribeToTopic("/topics/myapp");
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(refreshedToken);
}
/**
* Persist token to third-party servers.
*
* Modify this method to associate the user's FCM InstanceID token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
}
Notification payload
{
"to": "/topics/mytopic",
"priority": "high",
"notification": {
"sound": "default",
"badge": "1",
"body": "the body text",
"title": "title text"
},
"data": {
"id": "id",
"channel": "channel"
}
}
EDIT - Add code for WakeFulBroadcastReceiver
public class NotificationReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// cancel any further alarms
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmMgr.cancel(alarmIntent);
completeWakefulIntent(intent);
// start the GcmTaskService
MyAppFirebaseMessagingService.showNotification(context);
}
}
UPDATE PAYLOAD
If I change my payload to the suggested way in the comments like this it is still not working. Maybe it has something to do with the Huawei P8 Lite that I'm testing on with Android 6.0.1 installed.
{
"to": "/topics/mytopic",
"priority": "high",
"data": {
"sound": "default",
"badge": "1",
"body": "the body text",
"title": "title text"
}
}
UPDATE 2.0
I've tested on multiple devices and versions. On devices with Android 5 it was working fine, also without app open and screen locked. Only device it wasn't working was my own Huawei P8 Lite. Still can't figure out why it's not working on that one.
When the app is closed, it shutdowns the service. You must to restart the service.
On your Application class, implements ActivityLifecycleCallbacks and on onActivityDestroyed restart the service with an alarm.
public class YourApplication extends Application implements Application.ActivityLifecycleCallbacks {
#Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
#Override
public void onActivityDestroyed(Activity activity) {
Intent restartService = new Intent(getApplicationContext(), MyAppFirebaseMessagingService.class);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(),1,restartService,PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME,5000,pendingIntent);
}
}
I also had issues with devices not receiving the notifications when they were closed, like they would be after a restart.
Turned out, it wasn't working with a DEBUG version of the solution, so that had to be tested in RELEASE MODE. For those using Android Studio, press the Green Play Button next to the debug button.
Firebase has different types of notifications, and each has special handling.
Assuming you're using a data push, you don't need special handling or a WakefulBroadcastReceiver.
If you're using a notification push, the notification will appear automatically in the system tray. You cannot do any special handling there.
Check the official documents here: https://firebase.google.com/docs/cloud-messaging/android/receive

Not receiving GCM notifications with app in background and content-available=1

I developing an Ionic 2 app and testing on Android emulator.
When the app is in background and the notification has no title, no message and content-available=1 the notification should be sent directly to app notification handler. But its not happening.
I can receive notifications with the app in foreground.
If I have a title and a message I receive the notification in the notification area. But I need to send the notification directly to the app in silent mode, without pass by the notification area.
Here is my code to send push notifications:
{
"delay_while_idle": true,
"priority": "high",
"sound": "default",
"color": "FFFF00",
//payload
"data": {
"content-available": "1",
"some_var": "some_value",
"ohter_var": "other_value",
}
}
How could I sent silent notifications to my Android app?
Android GCM and FCM both also work when app background.
For that you need to add below service classes at manifest with intent Filter.
<!-- [START gcm_listener] -->
<service
android:name=".gcm.GcmListener"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name=".gcm.TokenRefreshService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID" />
</intent-filter>
</service>
<service
android:name=".gcm.RegistrationIntentService"
android:exported="false" />
<!-- [END gcm_listener] -->
public class GcmListener extends GcmListenerService {
}
public class TokenRefreshService extends InstanceIDListenerService {
#Override
public void onTokenRefresh() {
super.onTokenRefresh();
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
To get token:
public class RegistrationIntentService extends IntentService {
// TODO: Rename actions, choose action names that describe tasks that this
private String TAG = "RegistrationIntentService";
public RegistrationIntentService() {
super("RegistrationIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken("PRODUCT_ID",
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
}
}

GCM 3.0 - gcm doesn't automatically show notification with notification parameter

The new GCM 3.0 should allow GCM to automatically display notifications sent from server if they contain the notification parameter.
As said in the docs:
The notification parameter with predefined options indicates that GCM will display the message on the client app’s behalf if the client app implements GCMListenerService on Android
However I have trouble getting that to work even though the GCMListenerService is implemented.
AndroidManifest.xml
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="cz.kubaspatny.pushservertest" />
</intent-filter>
</receiver>
<service
android:name="cz.kubaspatny.pushservertest.gcm.CustomGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
CustomGcmListenerService.java
public class CustomGcmListenerService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle extras) {
super.onMessageReceived(from, extras);
Log.d("GcmListenerService", "Received gcm from " + from + " with bundle " + extras.toString());
}
}
The notification from server is logged but not shown by GCM.
Received gcm from 333813590000 with bundle Bundle[{notification={"icon":"ic_launcher.png","body":"great match!","title":"Portugal vs. Denmark"}, collapse_key=do_not_collapse}]
The message sent from server:
{
"registration_ids":[...],
"data": {
"notification" : {
"body" : "great match!",
"icon" : "ic_launcher.png",
"title" : "Portugal vs. Denmark"
}
}
}
Is there anything else needed to be done to allow the automatic display?
Try making the notification field a sibling of the data field. The data field is passed to onMessageReceived and the notification field is used to automatically generate the notification.
{
"registration_ids":[...],
"notification" : {
"body" : "great match!",
"icon" : "ic_launcher.png",
"title" : "Portugal vs. Denmark"
}
}

Categories

Resources