iOS fetch() POST fails if called too soon, with app running in background

This issue has been created since 2022-11-17.

Description

I use deeplinks to launch/focus my app from a webpage.

The link looks like ttgm://something

I parse the "something" and immediately make a fetch call.

80% of the time this fetch call fails, IF it's a POST (switching it out for a GET works 100% of the time)...

TypeError: Network request failed
at anonymous (http://192.168.0.20:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.thxyzabc.defhty:22664:33)
at apply (native)
at anonymous (http://192.168.0.20:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.thxyzabc.defhty:27853:26)
at _callTimer (http://192.168.0.20:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.thxyzabc.defhty:27788:17)
at callTimers (http://192.168.0.20:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.thxyzabc.defhty:27948:19)
at apply (native)
at __callFunction (http://192.168.0.20:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.thxyzabc.defhty:5307:36)
at anonymous (http://192.168.0.20:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.thxyzabc.defhty:5057:31)
at __guard (http://192.168.0.20:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.thxyzabc.defhty:5255:15)
at callFunctionReturnFlushedQueue (http://192.168.0.20:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=com.thxyzabc.defhty:5056:21)

The fetch call is over https (no issues with NSAllowsArbitraryLoads, etc), and works "sometimes".

I am debugging with Flipper.

If I add a short sleep for 500ms before making the call it works.

e.g.

            try {
                await new Promise( resolve => setTimeout( resolve, 500 ) );
            }
            catch ( error )
            {
                this.showOverlay( { type: 'error' } );

                Log.error( { function: _function, error: error } );
            }

I have seen this issue for many years and had old comments in my code to use GETs to work around this issue, but recently re-factored and used POSTs everywhere.

Version

0.70

Output of npx react-native info

info Fetching system and libraries information...
System:
OS: macOS 12.3.1
CPU: (8) x64 Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
Memory: 11.35 GB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 19.1.0 - /usr/local/bin/node
Yarn: Not Found
npm: 8.19.3 - /usr/local/bin/npm
Watchman: 2022.11.14.00 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.11.3 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 21.2, iOS 15.2, macOS 12.1, tvOS 15.2, watchOS 8.3
Android SDK: Not Found
IDEs:
Android Studio: 2021.3 AI-213.7172.25.2113.9123335
Xcode: 13.2.1/13C100 - /usr/bin/xcodebuild
Languages:
Java: 11.0.17 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.1.0 => 18.1.0
react-native: 0.70.6 => 0.70.6
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found

Steps to reproduce

Create app that accepts deeplinks.

Linking.addEventListener( 'url', ... )

Link from a webpage to launch the app.

Snack, code example, screenshot, or link to a repository

App.js

import { AppError, Log, API } from './src/Helpers';

export default class extends React.Component
{
deeplinkListener( data )
{
this.handleDeeplink( data.url );
}

async componentDidMount()
{
    try
    {
        Linking.addEventListener( 'url', this.deeplinkListener );
    }
    catch ( error )
    {
        console.log( error );
    }
}


async handleDeeplink( url )
{
    try {

        let matches = url.match( /(\d+(a|g|u)[a-f0-9]+)/ );

        Log.debug( _function + ": matches: ", matches );

        if ( matches && matches[ 1 ] && matches[ 2 ] && matches[ 2 ] === 'a' )
        {
            const key = matches[ 1 ];

            Log.debug( _function + ": Calling getList with key " + key );

            const response = await API.getList( {
                key: key,
            } );
        }
    }
    catch ( error )
    {
        this.hideOverlay();

        Log.error( { function: _function, error: error } );   // we include the _function again incase something deeper throws an error
    }
}

}

Helpers.js

class API
{
static async _call( path, timeout, args )
{
try {
var url = 'https://www.mydomain.com' + path;

        if ( ! args )
        {
            args = {};
        }

        args._context = Platform.OS;

        args._version = VersionInfo.appVersion;

        let response = null;

        const options = {
            credentials: 'include',
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify( args ),
        };

        response = await fetch( url, options );

        if ( ! response.ok )
        {
            throw new AppError( "Request Failed", { response } );
        }

        const json = await response.json();

        return json;        
    }
    catch ( error )
    {
        Log.debug( error, error.stack );

        throw error;
    }
}

static async getList( args )
{
    return this._call( '/api/app/get-list.json', 0, args );
}

}

intergalacticspacehighway wrote this answer on 2022-11-18

@robsco this is the behavior of native iOS NSURLRequest. I had encountered the same issue in past. Wrote it over here. Sorry, it's on Twitter 😅.

Apple developer thread of the issue https://developer.apple.com/forums/thread/106838

robsco wrote this answer on 2022-11-18

At least I'm not going mad.

I did find it a bit weird it only seems to happen with POST requests - did you see the same, or any type of request?

intergalacticspacehighway wrote this answer on 2022-11-18

yeah. I felt the same. It was surprising seeing requests getting cancelled. I am not sure about GET requests. I am out on a trip right now, would’ve tried it otherwise. Can you try a GET request with larger payload?
akaik iOS pauses downloads if not put in a background task, so might be same for GET requests?

This thread also highlights the same issue - AFNetworking/AFNetworking#4279

More Details About Repo
Owner Name facebook
Repo Name react-native
Full Name facebook/react-native
Language JavaScript
Created Date 2015-01-09
Updated Date 2022-12-10
Star Count 106395
Watcher Count 3660
Fork Count 22685
Issue Count 2288

YOU MAY BE INTERESTED

Issue Title Created Date Comment Count Updated Date
Multitask config files. 3 2022-06-06 2022-12-02
用https://xxxx.con:1234/d/可以不用密码下载任何文件 3 2022-12-03 2022-12-03
Watched status with External Player 1 2019-12-31 2022-10-30
Anvil: Address already in use 5 2022-07-19 2022-11-11
Provide dstorage.h header in C compatible way 1 2022-03-14 2022-12-01
Split generated classes and interfaces into dedicated files 1 2021-03-22 2022-11-07
Task configuration seems not to load 4 2021-03-12 2022-11-07
x/X causes "Wrong type argument: char-or-string-p, nil" 3 2017-04-11 2022-10-31
Maybe V+ changed something on their Github? 1 2021-05-23 2022-11-21
[Release Radar Request] Appsmith 1 2022-02-16 2022-11-30
[Feature Request]: Add audio file to a card 3 2021-09-26 2022-10-28
Dependency issue with react v17+ and npm v7+ 4 2021-01-15 2022-09-27
The image is selected by pressing quickly on the next or previous image 0 2021-03-26 2022-10-04
Max slew violations 3 2022-06-14 2022-08-29
Seek video on iOS with react-native-reanimated cause randomly crash at launch and in release mode only 11 2021-12-14 2022-10-26
Add tap back like feature to Messaging 3 2021-12-29 2022-11-10
Data mismatch between custom question and raw sql query with Redshift 17 2022-01-25 2022-12-02
Pie or donut charts turn off the total function 1 2022-01-25 2022-12-02
Filter values in embedded dashboards don't work after the upgrade to v0.41.6 - "Missing ID" 4 2022-01-25 2022-12-02
[BUG] a weird bug in tabliss while using it with unsplash background remains unchanged 1 2021-10-25 2022-10-22
[v4 & v3] - All text-based fields created by the user in the Content-Type Builder have the wrong autocomplete HTML parameter 3 2021-10-11 2022-12-02
Make expiration check automatic within each storage implementation 0 2022-06-17 2022-10-08
Terminal Plugin issues a 'items is not an attribute of line" error when executing any shell command ... and fix 2 2020-04-19 2022-10-30
(Bug report) The picture address of shared notes cannot be referenced 0 2022-04-26 2022-04-21
@ngrx/component: Use "global" rendering strategy in zoneless mode 0 2022-03-09 2022-11-14
bugly 发现了会崩溃,log如下 7 2018-06-01 2022-01-15
Order Editing: Inability to clear email 1 2021-10-01 2022-11-12
Usage data generation script should have ability to generate usage data in json format. 0 2021-11-17 2022-09-27
Add Pub/Sub as a new share channel 0 2021-06-29 2022-10-31
Format metrics keys correctly 0 2022-07-27 2022-08-22
Error #13: Assertion failure at kmp_dispatch.cpp(1298) Mac M1 Ultra 2 2022-10-10 2022-10-14
Staging branch for hydra 3 2022-02-23 2022-12-07
`setImage` convenience method 0 2021-08-17 2022-10-08
python3.6 logging is broken with Never grad 0.4.2.post6 1 2021-09-23 2022-11-22
[Bug] Wrong MIME type for atom.xml 0 2020-11-10 2022-11-28
StackOverflowError in ModelContext.unalias when running dukat on @pulumi/aws 4 2020-12-28 2022-11-03
Update dependencies 1 2015-11-11 2022-01-04
Manga with large amount of chapters get stuck updating 1 2021-11-29 2022-08-01
Scenes execute when starting edit 1 2022-03-10 2022-10-20
Client Allocation Request for: CATSplayground 3 2022-01-06 2022-01-24
Notary Application: Fei Yan - Kernelogic 10 2022-11-09 2022-11-09
Notary Application: Greaterheat 2 2022-11-09 2022-11-09
Notary Application: Sequoia Protocol 5 2022-11-09 2022-11-09
Notary Application: RawTech Ventures 2 2022-11-10 2022-11-09
Proposal: allow notaries to vote and automatically top up multisig LDN 16 2022-11-10 2022-11-09
Errors in README example 1 2019-11-20 2022-10-06
Vagrant confused between two virtual boxes with SSH | Mac OS Big Sur | VMWare Fusion 3 2022-09-23 2022-11-16
Docker APIv2 `/commit` endpoint is not updating `Cmd` of image 8 2022-04-04 2022-12-02
parseVersion undefined in Parse's Installation table 2 2020-10-13 2022-12-09
Pod Security Standards, non-root groups optional 3 2021-12-16 2022-12-02