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

rn-fetch-blob Implementation for React Native for Windows #701

Open
wants to merge 35 commits into
base: master
Choose a base branch
from

Conversation

avmoroz
Copy link

@avmoroz avmoroz commented Dec 1, 2020

Created an implementation of rn-fetch-blob for React Native for Windows.

@avmoroz avmoroz changed the title Dev rn-fetch-blob Implementation for React Native for Windows Dec 1, 2020
@stmoy
Copy link

stmoy commented Dec 2, 2020

We'll need to figure out what to do about this PR since it looks like this repo is no longer maintained (#666).

Even so, I think it's worthwhile to iterate here while we figure out that plan. In other words, lets see if we can get this PR as finished as possible so that wherever it ends up, it'll be clean and ready to go!

CC: @vmoroz @jonthysell @NickGerleman @asklar @bzoz - FYI

@avmoroz avmoroz marked this pull request as draft December 2, 2020 23:15
Copy link

@syedibrahimt syedibrahimt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File path now working fine

@jaimecbernardo
Copy link

jaimecbernardo commented Jan 21, 2021

Hi @avmoroz,
I've tested this module with react-native-pdf on Windows and it doesn't seem to be behaving as expected.
I've debugged a bit and was able to create some reproduction code based on react-native-pdf internals.

These are the App.js contents:

import React from 'react';
import {
  Button
} from 'react-native';

import RNFetchBlob from 'rn-fetch-blob';

const App: () => React$Node = () => {
  return (
    <Button title="Download a pdf file"
      onPress = { () => {
        const cacheFile = RNFetchBlob.fs.dirs.CacheDir + '/sample.pdf';
        RNFetchBlob.config({
          path: cacheFile,
          trusty: true
        }).fetch(
          'GET',
          'http://samples.leanpub.com/thereactnativebook-sample.pdf'
        ).then( 
          async (res) => {
            let a = 0;
            if (res && res.respInfo && res.respInfo.headers && !res.respInfo.headers["Content-Encoding"] && !res.respInfo.headers["Transfer-Encoding"] && res.respInfo.headers["Content-Length"]) {
              const expectedContentLength = res.respInfo.headers["Content-Length"];
              let actualContentLength;
                try {
                    const fileStats = await RNFetchBlob.fs.stat(res.path());
                    if (!fileStats || !fileStats.size) {
                        throw new Error("FileNotFound:" + source.uri);
                    }
                    actualContentLength = fileStats.size;
                    alert('Expected content length:' + expectedContentLength + ' Actual content length: ' + actualContentLength);
                } catch (error) {
                    alert("DownloadFailed: " + error);
                }
            } else {
              alert('Response headers were not the expected ones.');
            }
          }
        ).catch(
          (error) => alert("Fetch call failed: " + error)
        )
      }}
    />
  );
};

export default App;

This is the way I've set up the project on Windows:

npx react-native init TestRNFetchBlob --template react-native@^0.63.2
cd TestRNFetchBlob
npx react-native-windows-init --overwrite
yarn add joltup/rn-fetch-blob#701/head
npx react-native run-windows

On Windows, I get an alert with "Response headers were not the expected ones." and I find that no file seems to have been saved.

When running the same application for Android (npx react-native run-android), I get the message box with the "Expected content length" and "Actual content length" with equal values.

I hope this is helpful in getting similar behavior for the Windows implementation.

}
else
{
promise.Reject("EUNSPECIFIED: Failed to write to file.");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably want to pass the hresult at least. You can use the hresult_error's message() member function to get a string representation of the error

}
catch (...)
{
promise.Reject("EEXIST: File already exists."); // TODO: Include filepath
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not always going to be a file already exists here

}
else
{
promise.Reject("Invalid encoding");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log out the encoding as part of the rejection message

{
httpMethod = winrt::Windows::Web::Http::HttpMethod::Get();
}
else if (method.compare("POST") != 0 && method.compare("post") != 0)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can just be an else

@asklar
Copy link

asklar commented Jan 21, 2021

@jaimecbernardo good catch. I think the current PR is returning the content stream as the res, so the response info, headers, etc. is only used for progress notifications, and once it's completed, it is thrown away and not available to the JS code. Seems like a good thing to add if it is part of the module API/contract.

@RonRadtke
Copy link

RonRadtke commented Jan 23, 2021

Hey,
I forked the repo and would like to try to maintain it. If anyone wants to help, feel free to contact me. After giving it a start with some fixes for Android I would like to integrate the windows implementation. I would bring it to npm too then
Would that be OK for you? @asklar @avmoroz @stmoy @syedibrahimt

@asklar
Copy link

asklar commented Jan 23, 2021

Hey,
I forked the repo and would like to try to maintain it. If anyone wants to help, feel free to contact me. After giving it a start with some fixes for Android I would like to integrate the windows implementation. I would bring it to npm too then
Would that be OK for you? @asklar @avmoroz @stmoy @syedibrahimt

that would be fine by me seeing as this repo is marked as unmaintained :) thanks for volunteering! Once things are up and running we should also update the reactnative.directory site.

@RonRadtke
Copy link

@asklar yes, absolutely right. I will see what I can get done the next days

@RonRadtke
Copy link

@avmoroz @asklar I integrated it in my repo here: https://github.com/RonRadtke/react-native-blob-util

Copy link

@jaimecbernardo jaimecbernardo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested the changes and it looks like the files are now being saved on disk. There's some flakiness on this when used with react-native-pdf, though, to which I'm still trying to get to the bottom of.
On Windows, I still get an alert with "Response headers were not the expected ones." for the sample I gave earlier.

{
callback("Source file not found.");
}
callback(winrt::to_string(ex.message()).c_str());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the error is 0x8007002, callback is called twice, which is causing a runtime error crash.

Copy link

@asklar asklar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to leave a comment in the file but there's a github outage, let's see if this works.
This needs a #include <windows.h> in the module's pch.h

@jaimecbernardo
Copy link

^ I've fixed the current build issues I was facing on this module with a #include <unknwn.h> in the module's pch.h file.

@br4in3x
Copy link

br4in3x commented Dec 9, 2021

@avmoroz hello, for some reason I can not build the solution of the windows implementation in Visual Studio. First, I had to change this in the RNFetchBlob.vcxproj file:

<PropertyGroup Label="ReactNativeWindowsProps">
  <ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
</PropertyGroup>

to

  <PropertyGroup Label="ReactNativeWindowsProps">
    <ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(SolutionDir), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
  </PropertyGroup>

I'm running in a monorepo, so without this change, the solution is trying to load RNW from a location that doesn't contain RNW. Then, when I tried to build the project, I've got the following errors:

1>------ Build started: Project: RNFetchBlob, Configuration: Debug x64 ------
1>JsiApiContext.cpp
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(9,40): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(9,29): error C2146: syntax error: missing ';' before identifier '__ImageBase'
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(34,5): error C2065: 'HMODULE': undeclared identifier
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(34,13): error C2146: syntax error: missing ';' before identifier 'currentDllHanlde'
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(34,13): error C2065: 'currentDllHanlde': undeclared identifier
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(34,56): error C2061: syntax error: identifier 'HMODULE'
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(35,101): error C2065: 'currentDllHanlde': undeclared identifier
1>C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\XamlCompiler\Microsoft.Windows.UI.Xaml.Common.targets(482,5): error MSB4181: The "CompileXaml" task returned false but did not log an error.

It's weird because it's errors in RNW.. And it's only happening for this project only, which means something in the solution makes errors to appear. Other community native modules are built fine.

I'm using react-native-windows 0.64.23.

@asklar
Copy link

asklar commented Dec 9, 2021

@avmoroz hello, for some reason I can not build the solution of the windows implementation in Visual Studio. First, I had to change this in the RNFetchBlob.vcxproj file:

<PropertyGroup Label="ReactNativeWindowsProps">
  <ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
</PropertyGroup>

to

  <PropertyGroup Label="ReactNativeWindowsProps">
    <ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(SolutionDir), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
  </PropertyGroup>

I'm running in a monorepo, so without this change, the solution is trying to load RNW from a location that doesn't contain RNW. Then, when I tried to build the project, I've got the following errors:

1>------ Build started: Project: RNFetchBlob, Configuration: Debug x64 ------
1>JsiApiContext.cpp
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(9,40): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(9,29): error C2146: syntax error: missing ';' before identifier '__ImageBase'
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(34,5): error C2065: 'HMODULE': undeclared identifier
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(34,13): error C2146: syntax error: missing ';' before identifier 'currentDllHanlde'
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(34,13): error C2065: 'currentDllHanlde': undeclared identifier
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(34,56): error C2061: syntax error: identifier 'HMODULE'
1>C:\Users\HP\Code\f1\apps\MyHP\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\JSI\JsiApiContext.cpp(35,101): error C2065: 'currentDllHanlde': undeclared identifier
1>C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\XamlCompiler\Microsoft.Windows.UI.Xaml.Common.targets(482,5): error MSB4181: The "CompileXaml" task returned false but did not log an error.

It's weird because it's errors in RNW.. And it's only happening for this project only, which means something in the solution makes errors to appear. Other community native modules are built fine.

I'm using react-native-windows 0.64.23.

@br4in3x please use the version in https://github.com/RonRadtke/react-native-blob-util/ - the joltup/rn-fetch-blob repo is unmaintained.

@ikkyu-3 ikkyu-3 mentioned this pull request Jan 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants