Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FCM default icon uses invalid gradient

The default FCM icon of the Android manifest is not used. Instead the Android standart icon is used. In the logcat it says:

E/FirebaseMessaging: Icon with id: 2131230849 uses an invalid gradient. Using fallback icon.

The default icon only contains one color. I tested it with multiple different icons but always the Android standart icon is used.

like image 983
TheRedhat Avatar asked Jan 07 '18 13:01

TheRedhat


2 Answers

UPDATE: fixed by firebase in version 12.0.0

The faulty code below has been updated with this and it works great on 8.0, while preventing the bug outlined in my original answer.

@TargetApi(26)
private final boolean zza(int var1) {
    if(VERSION.SDK_INT != 26) {
        return true;
    } else {
        try {
            if(this.zzb.getResources().getDrawable(var1, (Theme)null) instanceof AdaptiveIconDrawable) {
                Log.e("FirebaseMessaging", (new StringBuilder(77)).append("Adaptive icons cannot be used in notifications. Ignoring icon id: ").append(var1).toString());
                return false;
            } else {
                return true;
            }
        } catch (NotFoundException var2) {
            return false;
        }
    }
}

This doesnt solve the issue, but from the comments I was asked to put it as an answer. Here is the code from firebase 11.8.0 that is the culprit and only on Android 8.0 (API 26). The reason for this check is because there is an Android 8.0 notification bug with adaptive icons https://www.bleepingcomputer.com/news/mobile/android-oreo-adaptive-icons-bug-sends-thousands-of-phones-into-infinite-boot-loops/ so this code prevents that, but in doing so, also prevents non-adaptive icons from showing up properly

    @TargetApi(26)
private final boolean zzid(int var1) {
    if(VERSION.SDK_INT != 26) {
        return true;
    } else {
        try {
            Drawable var2;
            if((var2 = this.mContext.getResources().getDrawable(var1, (Theme)null)).getBounds().height() != 0 && var2.getBounds().width() != 0) {
                return true;
            } else {
                Log.e("FirebaseMessaging", (new StringBuilder(72)).append("Icon with id: ").append(var1).append(" uses an invalid gradient. Using fallback icon.").toString());
                return false;
            }
        } catch (NotFoundException var3) {
            return false;
        }
    }
}

I've noticed in my logcat, that my app hits this code twice per notification, it tries for my notification drawable which i set in the manifest as per Firebase's instructions, then hits it again trying to do it for the launcher icon. Both fail, even when I make them solid color drawables.

As per another comment from southrop, the firebase team is aware of the issue and working on a fix but no timeline given.

This code is not in 11.6.0 and lower, so if you really need this working for the time being, downgrade your firebase.

Hope this helps others who find this post searching for the error

like image 59
djxstream Avatar answered Nov 15 '22 17:11

djxstream


This bug happens only if your application targeting API 26 (or greater) and you use Firebase 11.8.0 and launching it on device with Android 8.0. So I decided to fix it only for these version. The workaround: You should override Application class and override it's getResources() to return patched Resources class:

@Override public Resources getResources() {
    if (resources == null) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
            resources = new ResourcesForSupportFirebaseNotificationsOnAndroid8(super.getResources());
        } else {
            resources = super.getResources();
        }
    }
    return resources;
}

And you should create patched for our purposes Resources class:

public class ResourcesForSupportFirebaseNotificationsOnAndroid8 extends Resources {

    private final Resources resources;

    public ResourcesForSupportFirebaseNotificationsOnAndroid8(final Resources resources) {
        super(resources.getAssets(), resources.getDisplayMetrics(), resources.getConfiguration());
        this.resources = resources;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override public Drawable getDrawable(final int id, @Nullable final Theme theme) throws NotFoundException {
        if (id == R.drawable.ic_firebase_notification) {
            final Drawable drawable = resources.getDrawable(id, theme);
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            return drawable;
        } else {
            return resources.getDrawable(id, theme);
        }
    }
}

And check that your AndroidManifest.xml contains this meta-data:

<meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_firebase_notification"
        />

If you will do as described all notifications on Android 8.0 that will be rendered by Firebase SDK will be shown with default icon @drawable/ic_firebase_notification

But I hope that Firebase team fix their harmfull check and read how it's works

like image 10
Eugene Nefedov Avatar answered Nov 15 '22 16:11

Eugene Nefedov