Skip to content

NullPointerException in Android Remote Config callback #391

Description

@svprdga

Description

We are seeing a crash on Android when using countly_flutter Remote Config. The crash happens after calling remoteConfig.downloadAllKeys(...), when the native Android SDK finishes the remote config request and tries to notify Flutter through the plugin channel.

It looks like CountlyFlutterPlugin.notifyPublicChannelRCDL(...) calls publicChannel.invokeMethod(...) while publicChannel is null.

Package version

  countly_flutter: 26.1.0

Platform

  • Flutter app
  • Android
  • Countly Flutter SDK 26.1.0

Usage

  Countly is initialized with config:

  final CountlyConfig config = CountlyConfig(
    serverUrl,
    appKey,
  )
    ..setRequiresConsent(true)
    ..setConsentEnabled([CountlyConsent.remoteConfig]);

  await Countly.initWithConfig(config);

Then Remote Config is fetched:

  await Countly.instance.remoteConfig.downloadAllKeys((
    RequestResult result,
    String? error,
    bool fullValueUpdate,
    Map<String, RCData> values,
  ) {
    // Handle downloaded values
  });

In our app this fetch is started asynchronously shortly after initialization.

Crash

  java.lang.NullPointerException: Attempt to invoke virtual method 'void io.flutter.plugin.common.MethodChannel.invokeMethod(java.lang.String,
  java.lang.Object)' on a null object reference
      at ly.count.dart.countly_flutter.CountlyFlutterPlugin.notifyPublicChannelRCDL(CountlyFlutterPlugin.java:88)
      at ly.count.dart.countly_flutter.CountlyFlutterPlugin$1.callback(CountlyFlutterPlugin.java:282)
      at ly.count.android.sdk.ModuleRemoteConfig.NotifyDownloadCallbacks(ModuleRemoteConfig.java:414)
      at ly.count.android.sdk.ModuleRemoteConfig.lambda$updateRemoteConfigValues$1$ly-count-android-sdk-ModuleRemoteConfig(ModuleRemoteConfig.java:110)
      at ly.count.android.sdk.ModuleRemoteConfig$$ExternalSyntheticLambda2.callback(D8$$SyntheticClass:0)
      at ly.count.android.sdk.ImmediateRequestMaker.onPostExecute(ImmediateRequestMaker.java:167)
      at ly.count.android.sdk.ImmediateRequestMaker.onPostExecute(ImmediateRequestMaker.java:16)
      at android.os.AsyncTask.finish(AsyncTask.java:771)
      at android.os.AsyncTask.access$900(AsyncTask.java:199)
      at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)
      at android.os.Handler.dispatchMessage(Handler.java:106)
      at android.os.Looper.loopOnce(Looper.java:226)
      at android.os.Looper.loop(Looper.java:313)
      at android.app.ActivityThread.main(ActivityThread.java:8663)
      at java.lang.reflect.Method.invoke(Method.java)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)

Expected behavior

The plugin should not crash if the Flutter MethodChannel is unavailable. It should either skip the callback or guard the call with a null check.

Suspected cause

The public channel appears to be nullable in the Android plugin lifecycle, but notifyPublicChannelRCDL(...) invokes it without checking whether it has been initialized or is still attached.

A defensive check around publicChannel.invokeMethod(...) would likely prevent the crash.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions