Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite requests to the graph API #2326

Open
5 tasks done
antoinepalazzolo opened this issue Jan 9, 2024 · 12 comments
Open
5 tasks done

Infinite requests to the graph API #2326

antoinepalazzolo opened this issue Jan 9, 2024 · 12 comments

Comments

@antoinepalazzolo
Copy link

Checklist before submitting a bug report

Xcode version

15.1.0

Facebook iOS SDK version

16.3.1

Dependency Manager

SPM

SDK Framework

Core

Goals

The goal is to use the Facebook SDK to track app events. The SDK is generating an infinite number of network requests to the Graph API. This behavior is observed with an HTTP proxy (without SSL proxy) and with Instruments. Each request is sent as a batch to the Graph API, which consistently returns a 400 status code error for each item in the batch. The SDK then repeats the same request, receiving the same error, creating a continuous loop.

This issue leads to unnecessary network traffic and potential performance degradation in the application.

Expected results

  • The SDK should not resend the same request after receiving a 400 error from the Graph API.
  • Appropriate handling of API errors without causing an infinite loop of requests.

Actual results

When the app starts, the SDK sends a batch request to the Graph API, which returns a 400 status code error for each item in the batch. The same request is then sent again, resulting in the same error response. This process repeats indefinitely.

Sample Request and Response (with SSL proxy enabled):

  • Request Body:
{
  "batch": "[{\"relative_url\":\"[REDACTED_EXISTING_FB_APP_ID]?fields=app_events_feature_bitmask%2Cname%2Cdefault_share_mode%2Cios_dialog_configs%2Cios_sdk_dialog_flows.os_version%2817.2.1%29%2Cios_sdk_error_categories%2Csupports_implicit_sdk_logging%2Cgdpv4_nux_enabled%2Cgdpv4_nux_content%2Capp_events_session_timeout%2Clogging_token%2Crestrictive_data_filter_params%2Caam_rules%2Csuggested_events_setting%2Cprotected_mode_rules%2Cauto_log_app_events_default%2Cauto_log_app_events_enabled%2Cauto_event_mapping_ios&format=json&include_headers=false&os_version=17.2.1&sdk=ios\",\"method\":\"GET\"},{\"relative_url\":\"[REDACTED_EXISTING_FB_APP_ID]?fields=app_events_feature_bitmask%2Cname%2Cdefault_share_mode%2Cios_dialog_configs%2Cios_sdk_dialog_flows.os_version%2817.2.1%29%2Cios_sdk_error_categories%2Csupports_implicit_sdk_logging%2Cgdpv4_nux_enabled%2Cgdpv4_nux_content%2Capp_events_session_timeout%2Clogging_token%2Crestrictive_data_filter_params%2Caam_rules%2Csuggested_events_setting%2Cprotected_mode_rules%2Cauto_log_app_events_default%2Cauto_log_app_events_enabled%2Cauto_event_mapping_ios&format=json&include_headers=false&os_version=17.2.1&sdk=ios\",\"method\":\"GET\"}]",
  "batch_app_id": "[REDACTED_EXISTING_FB_APP_ID]"
}
  • Response Body:
[
  {
    "code": 400,
    "body": "{\"error\":{\"message\":\"Unsupported get request. Object with ID '[REDACTED_EXISTING_FB_APP_ID]' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https:\\/\\/developers.facebook.com\\/docs\\/graph-api\",\"type\":\"GraphMethodException\",\"code\":100,\"error_subcode\":33,\"fbtrace_id\":\"__\"}}"
  },
  {
    "code": 400,
    "body": "{\"error\":{\"message\":\"Unsupported get request. Object with ID '[REDACTED_EXISTING_FB_APP_ID]' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https:\\/\\/developers.facebook.com\\/docs\\/graph-api\",\"type\":\"GraphMethodException\",\"code\":100,\"error_subcode\":33,\"fbtrace_id\":\"__\"}}"
  }
]

Preliminary Analysis:
The parameters auto_log_app_events_default and auto_log_app_events_enabled appear to be causing the request failure. These are related to the automatic logging of events feature, which is controlled by the FacebookAutoLogAppEventsEnabled property in the plist and the Settings.shared.isAutoLogAppEventsEnabled property at runtime. Notably, these parameters are still sent to the API even when not enabled at runtime.

Steps to reproduce

  1. Configure the Facebook iOS SDK with the following plist properties:
    • FacebookAdvertiserIDCollectionEnabled: YES
    • FacebookAppID: [redacted]
    • FacebookAutoInitEnabled: NO
    • FacebookAutoLogAppEventsEnabled: NO
    • FacebookClientToken: [redacted]
    • FacebookDisplayName: [redacted]
  2. Initialize the SDK in the application's ApplicationDelegate.shared.application(, didFinishLaunchingWithOptions: ) method.
  3. Observe the network traffic through an HTTP proxy or instruments.

Code samples & details

The stack trace generating the request:

-[FBSDKURLSessionTask start]	
__55-[FBSDKURLSession executeURLRequest:completionHandler:]_block_invoke	
-[FBSDKURLSession updateSessionWithBlock:]	
-[FBSDKURLSession executeURLRequest:completionHandler:]	
-[FBSDKGraphRequestConnection start]	
-[FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:]	
-[FBSDKServerConfigurationManager cachedServerConfiguration]	
-[FBSDKErrorConfigurationProvider errorConfiguration]	
-[FBSDKGraphRequestConnection errorFromResult:request:]	
__65-[FBSDKGraphRequestConnection _completeWithResults:networkError:]_block_invoke	
__NSARRAY_IS_CALLING_OUT_TO_A_BLOCK__	
-[__NSArrayM enumerateObjectsWithOptions:usingBlock:]	
-[FBSDKGraphRequestConnection _completeWithResults:networkError:]	
-[FBSDKGraphRequestConnection completeFBSDKURLSessionWithResponse:data:networkError:]
@ThanasethPatrickMongsup
Copy link

{
"batch": "[{"relative_url":"[REDACTED_EXISTING_FB_APP_ID]?fields=app_events_feature_bitmask%2Cname%2Cdefault_share_mode%2Cios_dialog_configs%2Cios_sdk_dialog_flows.os_version%2817.2.1%29%2Cios_sdk_error_categories%2Csupports_implicit_sdk_logging%2Cgdpv4_nux_enabled%2Cgdpv4_nux_content%2Capp_events_session_timeout%2Clogging_token%2Crestrictive_data_filter_params%2Caam_rules%2Csuggested_events_setting%2Cprotected_mode_rules%2Cauto_log_app_events_default%2Cauto_log_app_events_enabled%2Cauto_event_mapping_ios&format=json&include_headers=false&os_version=17.2.1&sdk=ios","method":"GET"},{"relative_url":"[REDACTED_EXISTING_FB_APP_ID]?fields=app_events_feature_bitmask%2Cname%2Cdefault_share_mode%2Cios_dialog_configs%2Cios_sdk_dialog_flows.os_version%2817.2.1%29%2Cios_sdk_error_categories%2Csupports_implicit_sdk_logging%2Cgdpv4_nux_enabled%2Cgdpv4_nux_content%2Capp_events_session_timeout%2Clogging_token%2Crestrictive_data_filter_params%2Caam_rules%2Csuggested_events_setting%2Cprotected_mode_rules%2Cauto_log_app_events_default%2Cauto_log_app_events_enabled%2Cauto_event_mapping_ios&format=json&include_headers=false&os_version=17.2.1&sdk=ios","method":"GET"}]",
"batch_app_id": "[REDACTED_EXISTING_FB_APP_ID]"
}

@cnjsyyb
Copy link

cnjsyyb commented Jan 20, 2024

same problem

@rromanchuk
Copy link

rromanchuk commented Jan 24, 2024

to zuck: just pull AppEvents completely and start over. S2S CAPI only until then.

to community: FB refuses to document the fingerprinting extinfo , so if you need to build your own sdk, it's something like this.

import Foundation
import CoreTelephony
import UIKit

public struct ExtInfoPayload: Codable {
    public let extinfo: [String]

    public init() {
        let carrierName = CTTelephonyNetworkInfo().subscriberCellularProvider?.carrierName ?? ""
        let processorCount = ProcessInfo.processInfo.processorCount
        let totalDiskSpace: Int64 = try! FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())[.systemSize] as! Int64
        let availableDiskSpace: Int64 = try! FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())[.systemFreeSize] as! Int64
        let bundleId = Bundle.main.bundleIdentifier ?? ""
        let shortVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
        let longVersion = Bundle.main.infoDictionary?[kCFBundleVersionKey as String] as? String  ?? ""

        let language = NSLocale.current.identifier
        let timeZoneAbbrev = NSTimeZone.system.abbreviation() ?? ""
        let screenRect = UIScreen.main.bounds
        let scale = String(format: "%.02f", UIScreen.main.scale)
        let timeZoneIdentifier = NSTimeZone.system.identifier
        
        let machine: String = {
            var systemInfo = utsname()
            uname(&systemInfo)
            return withUnsafePointer(to: &systemInfo.machine.0) { ptr in
                String(cString: ptr)
            }
        }()

        self.extinfo = [
            "i2",
            bundleId,
            shortVersion,
            longVersion,
            UIDevice.current.systemVersion,
            machine,
            language,
            timeZoneAbbrev,
            carrierName,
            String(Int(screenRect.size.width)),
            String(Int(screenRect.size.height)),
            scale,
            String(processorCount),
            String(totalDiskSpace),
            String(availableDiskSpace),
            timeZoneIdentifier
        ]
    }
}

@Jhood1101
Copy link

Hi baby

@Intouch-Song
Copy link

This issue arose from version 16.3.1. After downgrading to version 16.2.0, the functionality has been restored.

@Jerrot
Copy link

Jerrot commented Mar 6, 2024

Any news on this? Given that the Facebook SDK 16.2.x is not working with Xcode 15.3 (see #2353) this is becoming a serious problem now.
Even if the Xcode 15.3 problem should be solved soon (which I expect), this issue is still a blocker on top and the only remaining walkaround is to stick with Xcode 15.2 - until Apple requires Xcode 15.3.

@antoinepalazzolo
Copy link
Author

antoinepalazzolo commented Mar 6, 2024

It's been nearly two months since this issue was reported, and it appears that no one from the Facebook team has addressed it yet.

@scottlemke
Copy link

Was this fixed in 17.0? I would love to update to get the Privacy manifests, but if this is not fixed, I can't update.

@TimoWaelischIdealo
Copy link

It looks like it was silently fixed, but I would appreciate confirmation as well.

@TimoWaelischIdealo
Copy link

Hi @antoinepalazzolo, as you were the original author of this issue, can you confirm this is working for you as well since 17.0?
If so, we/you might close this ticket on our own, I have some... doubts on FB taking care of it.

@scottlemke
Copy link

FWIW, in our experience with testing out version 17.0 of the SDK, we have not seen this bug occur again. I would still like to see official confirmation.

@antoinepalazzolo
Copy link
Author

antoinepalazzolo commented Apr 12, 2024

The issue with the infinite loop of network requests in version 16.3.1 seems to be mitigated in version 17.0 of the SDK. Previously, the error was caused by the SDK attempting to retry the same request repeatedly when it failed to load the server configuration due to (erroneous ?) additional parameters. The infinit loop was observed in previous versions of the SDK when using an HTTP proxy that map the same error.

In version 17.0, there appears to be improved communication between the SDK and the backend, potentially avoiding this specific error scenario. However, without explicit confirmation that the underlying error handling mechanism has been redesigned to prevent similar issues, we cannot conclusively say the bug has been fixed. It may be beneficial to monitor the behavior in version 17.0 further before deciding to close the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants