Android/Firebase - Error While Parsing Timestamp in Gcm Event - Null Timestamp

Android/Firebase - Error while parsing timestamp in GCM event - Null timestamp

Even though notification is apparently a supported element (according to the Firebase web docs), the only way I could get rid of the exception was to remove it entirely, and use the data section only, and then in my app create a notification (rather than letting firebase do the notification).

I used this site to work out how to raise the notifications: https://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/

My notification now looks like the following:

    $fields = array("to" => "<valid-token>",
"data" => array("data"=>
array(
"message"=>"This is some data",
"title"=>"This is the title",
"is_background"=>false,
"payload"=>array("my-data-item"=>"my-data-value"),
"timestamp"=>date('Y-m-d G:i:s')
)
)
);
...
<curl stuff here>
...
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

My onMessageReceived looks like this:

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());

// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());

try {
JSONObject json = new JSONObject(remoteMessage.getData().toString());
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}

which calls handleDataMessage which looks like this:

private void handleDataMessage(JSONObject json) {
Log.e(TAG, "push json: " + json.toString());

try {
JSONObject data = json.getJSONObject("data");

String title = data.getString("title");
String message = data.getString("message");
boolean isBackground = data.getBoolean("is_background");
String timestamp = data.getString("timestamp");
JSONObject payload = data.getJSONObject("payload");

// play notification sound
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();

if (!NotificationUtils.isBackgroundRunning(getApplicationContext())) {
// app is in foreground, broadcast the push message
Intent pushNotification = new Intent(ntcAppManager.PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);

} else {
// app is in background, show the notification in notification tray
Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
resultIntent.putExtra("message", message);

showNotificationMessage(getApplicationContext(), title, message, timestamp, resultIntent);
}
} catch (JSONException e) {
Log.e(TAG, "Json Exception: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}

this then calls showNotificationMessage

/**
* Showing notification with text only
*/
private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, timeStamp, intent);
}

And subsequently notificationUtils.showNotificationMessage

public void showNotificationMessage(String title, String message, String timeStamp, Intent intent) {
showNotificationMessage(title, message, timeStamp, intent, null);
}

public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) {
// Check for empty push message
if (TextUtils.isEmpty(message))
return;

// notification icon
final int icon = R.mipmap.ic_launcher;

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent resultPendingIntent =
PendingIntent.getActivity(
mContext,
0,
intent,
PendingIntent.FLAG_CANCEL_CURRENT
);

final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
mContext);

final Uri alarmSound = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE
+ "://" + mContext.getPackageName() + "/raw/notification");

showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
playNotificationSound();

}

private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {

NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();

inboxStyle.addLine(message);

Notification notification;
notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setContentIntent(resultPendingIntent)
.setSound(alarmSound)
.setStyle(inboxStyle)
.setWhen(getTimeMilliSec(timeStamp))
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
.setContentText(message)
.build();

NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(ntcAppManager.NOTIFICATION_ID, notification);
}

More detail in the link above, and it's a lot of handling but at least the exception's gone and I'm in control of the notifications.

EDIT - Firebase Timestamp Causing 'Cannot read properties of null' error in HTML interpolation while adding new document

Alright, the solution is surprisingly simple but it took me a while to even figure out what the problem was. In the end, I went back to an article I had read when I was first working with firebase timestamps on medium. There is a lot of detail, but the upshot is that until the timestamp is finalized it's going to default returning a null value, which is what was causing my null error.

The solution is to use 'SnapshotOptions' to modify each documentsnapshot with an estimate of what the timestamp would be. I don't need nanosecond precision, so this is perfect for my usage.

In the end, my change wasn't even in something I had originally posted, it's inside of the service and is what returns the subscription for sessionSource in ngOnIt.

Below is the entire section, but all I did was add { serverTimestamps: 'estimate' } as an option to the payload.doc.data() function. This set's an estimated timestamp, and I no longer have the null errors.

 getSessionList(pid: string){

return this.afs.collection(this.CollectionPath+pid+'/Sessions', ref => ref.orderBy('startDate', 'desc')).snapshotChanges().pipe(
map(actions => {
return actions.map(a => {
const data = a.payload.doc.data({ serverTimestamps: 'estimate' }) as sessions_list;
const id = a.payload.doc.id;
return { id, ...data };
})
}
))
}

There is a similar question I found while looking for a solution.

Firebase Cloud Message Push Notifications giving errors

To fix the failed to post notification on channel null problem, you have to update your firebase-messaging version to latest or at least 15.0.2. Hope this will resolve the problem.

In addition to this you may add the below meta data in your AndroidManifest to double sure that it will work. Thanks

<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/default_notification_channel_id"/>

Xamarin.Forms Android app hangs when opened by tapping push message

Start your pushes by checking android OS first:

        if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
SetOreoNotification();
}
else
{
DispatchNotificationThatServiceIsRunning();
}

Then do this (taken from a project of mine that works fine on all Android devices:)

 void DispatchNotificationThatServiceIsRunning()
{
int id = 50;
try
{
RemoteViews contentView = new RemoteViews(PackageName, Resource.Layout.Notification);
contentView.SetTextViewText(Resource.Id.txt_crrentSong_notification, Activity_Player.txt_CurrentSong.Text);
contentView.SetTextViewText(Resource.Id.txt_crrentSong__artist_notification, Activity_Player.txt_CurrentArtist.Text);

notificationBuilder = new Notification.Builder(ApplicationContext);

Notification.Builder builder = new Notification.Builder(this)
.SetSmallIcon(Resource.Drawable.btn_icon_header)
.SetCustomContentView(contentView);

Task.Delay(_countDownFirstRound).ContinueWith(t =>
{
NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Notify(id, notificationBuilder.Build());

DispatchNotificationThatServiceIsRunning();//This is for repeate every 1s.

_countDownFirstRound = 50;

// Click on notification, and return to app. Only works, because _2TimerRunning is set as : "LaunchMode = LaunchMode.SingleInstance"
Intent notificationIntent = new Intent(this, typeof(Activity_Player));
notificationIntent.SetAction(Intent.ActionMain);
notificationIntent.AddCategory(Intent.CategoryLauncher);
PendingIntent contentIntent = PendingIntent.GetActivity(this, 1, notificationIntent, PendingIntentFlags.UpdateCurrent);
notificationBuilder.SetContentIntent(contentIntent);

},

TaskScheduler.FromCurrentSynchronizationContext());
}
catch
{
Toast.MakeText(this, "ERROR NOTIFY", ToastLength.Short).Show();
}
}

void SetOreoNotification()
{
RemoteViews contentView = new RemoteViews(PackageName, Resource.Layout.NotificationOreo);
contentView.SetTextViewText(Resource.Id.txt_crrentSong_notification_oreo, Activity_Player.txt_CurrentSong.Text);
contentView.SetTextViewText(Resource.Id.txt_crrentSong__artist_notification_oreo, Activity_Player.txt_CurrentArtist.Text);

const string URGENT_CHANNEL = "com.xamarin.myapp.urgent";
string chanName = "xy";
var importance = NotificationImportance.Default;
NotificationChannel chan = new NotificationChannel(URGENT_CHANNEL, chanName, importance);

chan.SetSound(null, null);

//chan.EnableVibration(true);

chan.LockscreenVisibility = NotificationVisibility.Private;

NotificationManager notificationManager =
(NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(chan);

Intent notificationIntent = new Intent(this, typeof(Activity_Player));
notificationIntent.SetAction(Intent.ActionMain);
notificationIntent.AddCategory(Intent.CategoryLauncher);
PendingIntent contentIntent = PendingIntent.GetActivity(this, 1, notificationIntent, PendingIntentFlags.UpdateCurrent);

Notification.Builder builder = new Notification.Builder(this)
.SetSmallIcon(Resource.Drawable.btn_icon_header)
.SetCustomContentView(contentView)
.SetChannelId(URGENT_CHANNEL)
.SetContentIntent(contentIntent)
.SetGroupAlertBehavior(NotificationGroupAlertBehavior.Summary)
.SetGroup("My group")
.SetGroupSummary(false);

const int NOTIFY_ID = 1100;
notificationManager.Notify(NOTIFY_ID, builder.Build());
}

Notification message seems to be empty when app is on foreground

This was solved by updating (1)firebase-messaging and (2)flutter_local_notifications to their latest versions.

Cant receive Notifications from FCM while the app is in Foreground state

I discovered the problem, It was that I am using Android O and didn't set the Channel ID for the notification which is a must if you want to receive it on Android 8.0 or higher

so here is the solution code

 private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = getString(R.string.channel_name);
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}


Related Topics



Leave a reply



Submit