24

The Android Facebook SDK is always making a network request to graph.facebook.com when calling FacebookSdk.sdkInitialize(context) even if nothing of the SDK has been used yet.

So if we're initializing it in the Application.onCreate() there will always be at least one network request. Even if the setting is as follows:

 <meta-data
    android:name="com.facebook.sdk.AutoLogAppEventsEnabled"
    android:value="false" />

We've took a closer look at this because a user complained that he is not using the Facebook Login (which is why we have the Facebook SDK in the first place) and still there is "user data" transferred to Facebook. In times of GDPR and suspicious users, this is a very unfavourable behaviour!

What we're doing now is calling FacebookSdk.sdkInitialize(context) only when the user wants to use the Facebook Login (at the time when the user clicks on the button). Additionally, we removed the meta-data for android:name="com.facebook.sdk.ApplicationId" from the AndroidManifest. This prevents the initial network request but then there is the following crash appearing in the CurrentAccessTokenExpirationBroadcastReceiver:

java.lang.RuntimeException: Unable to start receiver com.facebook.CurrentAccessTokenExpirationBroadcastReceiver: The SDK has not been initialized, make sure to call FacebookSdk.sdkInitialize() first.
at com.facebook.internal.Validate.sdkInitialized(Validate.java:143)
    at com.facebook.FacebookSdk.getApplicationContext(FacebookSdk.java:518)
    at com.facebook.AccessTokenManager.getInstance(AccessTokenManager.java:86)
    at com.facebook.CurrentAccessTokenExpirationBroadcastReceiver.onReceive(CurrentAccessTokenExpirationBroadcastReceiver.java:34)

Now there are several questions:

  1. Why is Facebook still making a request at start? If they want to validate the auth token, they can do it as soon as the SDK is really used...

  2. Does Facebook know and tolerate crashes when sdkInitialize() is not called? Because I fear when this NullPointerException is removed there will be other crashes...

  3. Most important: Are there any other ways to prevent network requests from the Facebook SDK when its features are not used?

mbo
  • 4,611
  • 2
  • 34
  • 54
  • 1
    Looks like they're currently working on a similar issue for iOS: https://developers.facebook.com/bugs/2049684891939638/ There is one for Android now, too: http://developers.facebook.com/bugs/1228749923934453/ – mbo Jul 17 '18 at 15:22
  • 2
    What version of sdk you're using and how exactly are you avoiding `FacebookSdk.sdkInitialize` being invoked. I'm using `com.facebook.android:facebook-core:4.34.0` and it's invoked with app start no code needed from my side in `Application.onCreate`. Manifest `AutoLogAppEventsEnabled` flag won't prevent fb making a call. It's `GET /v3.0/xxx?fields=..` and looks like a fetch config call but thanks, no thanks FB. GDPR handling teams say no. So how did you avoid `sdkInitialize` call? – fada21 Jul 18 '18 at 16:59
  • 2
    Do disable the initial call you need to remove ` – mbo Jul 19 '18 at 06:55
  • Will try that. Cheers. – fada21 Jul 24 '18 at 09:58
  • FacebookSdk.sdkInitialize(context) is now deprecated. Any non deprecated method instead ? Thanks. – toto_tata Dec 05 '18 at 17:10

2 Answers2

7

I have noticed that the Facebook SDK (at least in version 4.33) adds a provider (com.facebook.internal.FacebookInitProvider) in the manifest of your app, which automatically calls FacebookSdk.sdkInitialize with the application context.

Even if you have added:

<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false" />

in your manifest, at least 2 requests will be made to Facebook:

  • a graph request to get app settings
  • an Events request "fb_sdk_initialize" which logs all the Facebook frameworks that are included into your app

So to prevent these requests (that we don't want as long as the user didn't allow them (GDPR)), I think you did everything we need to do:

  • Do not add <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/> in the manifest
  • Add <meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false"/> in the manifest
  • Only initialize Facebook SDK when you need it.

Like this for example:

FacebookSdk.setApplicationId(<context>.getString(R.string.facebook_app_id));
FacebookSdk.sdkInitialize(<context>);
AppEventsLogger logger = AppEventsLogger.newLogger(<context>); // I don't use FB Login for my project but app events.

But regarding your crash, I don't know why it happens since it seems that the broadcast "com.facebook.sdk.ACTION_CURRENT_ACCESS_TOKEN_CHANGED" is sent locally.

Nevertheless, I think you can prevent it by adding this to your manifest:

<provider
    android:name="com.facebook.internal.FacebookInitProvider"
    tools:node="remove" />
<receiver
android:name="com.facebook.CurrentAccessTokenExpirationBroadcastReceiver"
    tools:node="remove" />

However, doing this may have bad consequences with the use of Facebook SDK and I think you will have to provide (and register in your manifest) your own BroadcastReceiver:

public class CustomCurrentAccessTokenExpirationBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (AccessTokenManager.ACTION_CURRENT_ACCESS_TOKEN_CHANGED.equals(intent.getAction())) {
            new CurrentAccessTokenExpirationBroadcastReceiver().onReceive(context, intent); // Call it only if you have initialized the Facebook SDK!
        }
    }
}
Donkey
  • 1,176
  • 11
  • 19
  • 1
    FacebookSdk.sdkInitialize(context) is now deprecated. Any non deprecated method instead ? Thanks. – toto_tata Dec 05 '18 at 17:09
  • 1
    Don't worry, this method is used internally. If it is deprecated, it's because it is expected to be called automatically by the SDK (see comment starting at line 250: https://github.com/facebook/facebook-android-sdk/blob/sdk-version-4.39.0/facebook-core/src/main/java/com/facebook/FacebookSdk.java). – Donkey Dec 07 '18 at 08:52
-2

According to Facebook Support,

If you would like to temporarily disable automatic events collection, such as to get end-user consent before collecting data, you can set the value of AutoLogAppEventsEnabled to false in the app's AndroidManifest.xml in the application tag.

For example:

<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false"/>

To re-enable collection, such as after an end-user provides consent, call the setAutoLogAppEventsEnabled() method of the FacebookSDK class.

For example: setAutoLogAppEventsEnabled(true);

If you need to suspend collection again for any reason, you can call setAutoLogAppEventsEnabled(false); and collection will be suspended until re-enabling it.

Kedar Tendolkar
  • 474
  • 3
  • 9
  • 2
    Thank you for copying the Facebook docs which everyone already read. I've switched off the setting and there is still one request like I've described in the question. I cannot believe that answer is auto-rewarded... – mbo Jul 27 '18 at 19:18
  • 1
    As @noongiya95 said this is NOT preventing a call which also was mentioned in the question. No value added in this answer, just noise. – fada21 Aug 22 '18 at 11:17