azure-sdk-for-js icon indicating copy to clipboard operation
azure-sdk-for-js copied to clipboard

Support for using sdk in React-Native

Open ehvattum opened this issue 4 years ago • 18 comments

My issue is regards to blob storage, but is suspect the issue is universal to the sdk.

It is impossible to use this client, or to generate a working client from the spec that can run in react native.

There are always incompatible dependencies included, especially from this projects' core-http. Compounding the problem: the spec is not valid swagger, so using a different generator does not work at all.

  • This issue was initially written in a kinder tone, but due to "Show related issues" deleting everything I had written, this is my ever more frustrated second attempt.

Updates:

  • This is a related issue: #4917 - mentions xmlbuilder and xml2js as examples.

ehvattum avatar Oct 24 '19 08:10 ehvattum

Thanks for reporting @ehvattum

Can you elaborate on the kind of incompatible dependencies that you have encountered when using the libraries that depend on core-http?

Or if you can point us to a sample app using react-native and say the blob library with steps to replicate the problem, that would be helpful too.

ramya-rao-a avatar Oct 24 '19 17:10 ramya-rao-a

@ramya-rao-a Issue updated: This is a related issue: #4917 - mentions xmlbuilder and xml2js as examples.

ehvattum avatar Oct 25 '19 08:10 ehvattum

Is there any updates/plans on this issue ?

AndriiDidkivsky avatar Jun 15 '20 14:06 AndriiDidkivsky

@AndriiDidkivsky sorry we don't have any concrete plan yet on the timeline. We know that one of our dependencies xml2js has circular dependency issue which prevents it from being used in reactive-native. However, we don't yet have a replacement xml parser. We are also working on separating out the xml parser dependency to a separate package, so it would not cause problems for users that don't depend on storage. Again, no ETA yet on when that would be available.

jeremymeng avatar Jun 15 '20 23:06 jeremymeng

I am receiving this error while bundling the react native project. Sharing this as it may help for integration.

error: Error: While trying to resolve module @azure/loggerfrom fileC:\Users\xxx\source\xxx\node_modules@azure\storage- blob\dist\index.js, the package C:\Users\xxx\source\xxx\node_modules@azure\logger\package.jsonwas successfully found. H owever, this package itself specifies amain module field that could not be resolved (C:\Users\xxx\source\xxx\node_module s@azure\logger\browser\logger.js`. Indeed, none of these files exist:

  • C:\Users\xxx\source\xxx\node_modules@azure\logger\browser\logger.js(.native|.android.jsx|.native.jsx|.jsx|.android.js|. native.js|.js|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx|.android.svg|.native.svg|.svg|.android.json|.native.json|.json) *`

sabrimev avatar Aug 19 '20 09:08 sabrimev

@jeremymeng Is there any new update? I saw it was tagged with milestones.

ewfian avatar Oct 17 '20 13:10 ewfian

I've been investigating what it would take to support react native with our SDKs today and with some changes I've been able to use some @azure/storage-blob and @azure/app-configuration APIs.

Here's what I've found so far.

package.json#react-native field

The react native bundler (metro) respects the browser and react-native mappings in package.json, but does not look at the module field. This means that for packages that have runtime specific logic (which is most of them), we need to at a minimum include a mapping from main to module. In practice this looks like:

{
  "react-native": {
    "./dist/index.js": "./dist-esm/src/index.js"
  }
}

Lack of Node.js and Browser APIs

react native uses JavaScriptCore for executing JavaScript code, and includes shims for a few APIs like fetch and XMLHttpRequest. However, it does not expose APIs like crypto, Text(Encoder|Decoder), or atob/btoa. It also doesn't include any node.js modules.

This means we really need to treat react native as a 3rd runtime, and many places where we have node and browser files today, we may need a react-native version as well.

crypto

The @azure/cosmos library uses isomorphic-webcrypto when running in react-native, and requires the user to install it themselves. This may be something we can depend on for our libraries that require signing (e.g. AppConfiguration).

DOMParser

React Native doesn't provide a way to build or parse XML. In node.js we use xml2js to handle building and parsing XML, but this package doesn't work in react native because it depends on some native node modules.

I did find another library - xmldom that exposes DOMParser and XMLSerializer with APIs that match those found in browsers, but it has not yet reached version 1.0.0. It has some subtle differences from the DOMParser in browsers, and doesn't expose everything that'd be nice to have as part of its public API (e.g. enums.) However I was able to get it working with storage-blob with some minor changes to the browser version of the xml utilities.

base64

React Native doesn't include a utility to do base64 encoding/decoding (e.g. atob/btoa). It appears that they used to have a utility package that was removed sometime prior to 0.60.x. However this can be solved by relying on the buffer module much like we do for browser builds.

Lack of some language-level features

for...await

The react-native toolchain handles TypeScript compilation itself. It currently lacks support for for...await loops, so operations that return AsyncIterableIterators can't be looped over this way. They do still work if you call next on the iterator. There may be a way to configure either the metro bundler or babel to support for...await but this is not strictly an SDK issue (since users can't write code that uses for...await.)

Authentication

Currently the credentials available in @azure/identity won't work in react-native and msal does not (yet?) support react-native either.

It is possible to use the react-native-app-auth package and create a custom TokenCredential to use with our packages.

Rough example:

import { authorize } from "react-native-app-auth";
import { TokenCredential } from "@azure/core-auth";

export class ReactNativeAadTokenCredential implements TokenCredential {
  constructor(private clientId: string, private redirectUrl: string, private tenant: string) {}

  getToken(scopes: string | string[]) {
    if (!Array.isArray(scopes)) {
      scopes = [scopes];
    }
    return authorize({
      clientId: this.clientId,
      redirectUrl: this.redirectUrl,
      issuer: `https://login.microsoftonline.com/${tenant}/v2.0`,
      scopes: scopes,
    }).then((result) => {
      const expiry = new Date(result.accessTokenExpirationDate).getTime();
      return {
        token: result.accessToken,
        expiresOnTimestamp: expiry,
      };
    });
  }
}

AMQP

Currently the biggest blocker for AMQP-based services (service-bus/event-hubs) is lack of react-native support in rhea. More investigation is needed here.

chradek avatar Dec 18 '20 22:12 chradek

Today we've got such a bad surprise when realized generated by the Autorest client does not work on the react-native ((

Taking in to account how popular react-native it can have higher priority, but, since it's hanging from 2019 I think we have no chance ((

yahorsi avatar Jun 16 '21 11:06 yahorsi

Thanks for sharing the feedback @yahorsi!

@chradek had taken some initial steps towards this in this semester, see #13232, but I agree that we did not get time to do anything more that. We are investing more time in this in the new semester (July-Dec 2021) and you should see more progress here.

ramya-rao-a avatar Jun 16 '21 23:06 ramya-rao-a

@chradek I am looking to use @azure/app-configuration in react-native. You have mentioned that you are able to get it working. Are these changes available in any release? I used used version 1.3.0 of @azure/app-configuration. However, I get issue with resolving node modules like 'crypto', 'http', 'https', etc.

prakashbask avatar Aug 13 '21 14:08 prakashbask

Hi All, is there any update on this matter? The milestone keeps being pushed forward since 2019, is there any progress?

egemenuzunali avatar Jan 31 '22 16:01 egemenuzunali

@prakashbask @egemenuzunali we were able to use app-configure in a proof-of-concept prototype. I plan to look into this issue in February and will update here.

jeremymeng avatar Jan 31 '22 18:01 jeremymeng

@jeremymeng amazing!! Thanks for the insights

egemenuzunali avatar Jan 31 '22 18:01 egemenuzunali

@egemenuzunali just an update. I am waiting for the work to move app-configuration to our newer version of core libraries #https://github.com/Azure/azure-sdk-for-js/issues/15809 first which should remove the need of hacky workaround. I should have an update before April.

jeremymeng avatar Mar 09 '22 22:03 jeremymeng

@jeremymeng Thanks a lot for the update 👍 , looking forward to taking it for a spin here at the Municipality of Amsterdam.

egemenuzunali avatar Mar 09 '22 22:03 egemenuzunali

Some (late) updates: at this time, I was able to run some samples of Storage blob/file share/file datalake/queue, Text Analytics, App Configuration, Data Tables in a React Native Expo project on the Android Emulator. Connection Strings/keys are used in testing. @azure/identity does not work at the moment. However, if an AAD access token is available via third party plugins/libraries, they can be used via a wrapper credential that implements the TokenCredential interface

For reference, if anyone is interested to give a try:

  • polyfills in shims.js, which is imported in App.js
import 'react-native-url-polyfill/auto';
import "react-native-get-random-values";
import "text-encoding-polyfill";
const getRandomValues = global.crypto.getRandomValues;
import * as crypto from "isomorphic-webcrypto";
global.crypto = crypto;
global.crypto.getRandomValues = getRandomValues;
  • dependencies
  "dependencies": {
    "@azure/ai-text-analytics": "5.2.0-beta.2",
    "@azure/app-configuration": "1.4.0-beta.1",
    "@azure/data-tables": "13.1.2-alpha.20220503.1",
    "@azure/storage-blob": "12.10.0",
    "@azure/storage-file-datalake": "12.9.0",
    "@azure/storage-file-share": "12.10.0",
    "@azure/storage-queue": "12.9.0",
    "@types/react": "^17.0.43",
    "@types/react-native": "^0.67.3",
    "babel-plugin-inline-dotenv": "^1.7.0",
    "expo": "~44.0.0",
    "expo-status-bar": "~1.2.0",
    "isomorphic-webcrypto": "^2.3.8",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "react-native-get-random-values": "~1.7.0",
    "react-native-url-polyfill": "^1.3.0",
    "react-native-web": "0.17.1",
    "text-encoding-polyfill": "^0.6.7"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@babel/plugin-proposal-async-generator-functions": "^7.16.8",
    "stream": "^0.0.2",
    "timers": "^0.1.1"
  },
  • babel config
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ["babel-preset-expo"],
    plugins: [
      "@babel/plugin-proposal-async-generator-functions",
      ["inline-dotenv", { unsafe: true }],
    ],
  };
};

jeremymeng avatar May 17 '22 18:05 jeremymeng

@prakashbask @egemenuzunali Please see this PR for a react-native (Expo) sample of using AppConfig SDK https://github.com/Azure/azure-sdk-for-js/pull/21907

jeremymeng avatar May 18 '22 00:05 jeremymeng

any news?

thank you

yahorsi avatar Aug 16 '22 08:08 yahorsi

@yahorsi which package(s) are you trying to use in react-native?

jeremymeng avatar Sep 09 '22 20:09 jeremymeng

Update: I just merged PR https://github.com/Azure/azure-sdk-for-js/pull/23610, which adds a sample showing Event Hubs and Service Bus JS SDK usage in React-Native.

Now we have samples show the usage of

jeremymeng avatar Nov 17 '22 19:11 jeremymeng

Great, will check and migrate to SDK in the next App release if everything is ok

AndriiDidkivsky avatar Nov 18 '22 08:11 AndriiDidkivsky