Describe the bug
After updating to 3.x we cannot use Amplify Storage. We are using named imports and Storage has been configured and in aws-exports.js we have the following lines (auto-generated) in relation to storage:
"aws_user_files_s3_bucket": "bucketname-prod",
"aws_user_files_s3_bucket_region": "us-east-1"
There's no AWSS3 value in that aws-exports.js file, and I'm frankly confused what is the right setup. Documentation seems to be related to 2.x and manual configuration is not in use here and was not needed in 2.x either.
The error is:
[Error] Unhandled Promise Rejection: No plugin found in Storage for the provider
(anonymous function)
rejectPromise
rejectPromiseWithFirstResolvingFunctionCallCheck
reject
(anonymous function) (7.11d9e661.chunk.js:2:72188)
(anonymous function) (7.11d9e661.chunk.js:2:69807)
(anonymous function) (7.11d9e661.chunk.js:2:68846)
Promise
ee (7.11d9e661.chunk.js:2:68606)
(anonymous function)
u (6.9289253a.chunk.js:2:1029567)
(anonymous function) (6.9289253a.chunk.js:2:1029317)
r (6.9289253a.chunk.js:2:58397)
s (6.9289253a.chunk.js:2:58601)
(anonymous function) (6.9289253a.chunk.js:2:58660)
Promise
(anonymous function) (6.9289253a.chunk.js:2:58551)
(anonymous function) (14.9a8a693a.chunk.js:1:11039)
os (6.9289253a.chunk.js:2:987807)
mu (6.9289253a.chunk.js:2:1006949)
(anonymous function) (6.9289253a.chunk.js:2:1025266)
Zs (6.9289253a.chunk.js:2:998224)
Zs
(anonymous function) (6.9289253a.chunk.js:2:949685)
(anonymous function) (6.9289253a.chunk.js:2:1025266)
Go (6.9289253a.chunk.js:2:949631)
qo (6.9289253a.chunk.js:2:949566)
Ks (6.9289253a.chunk.js:2:995083)
ga (6.9289253a.chunk.js:2:966801)
ga
next (14.9a8a693a.chunk.js:1:40963)
b (6.9289253a.chunk.js:2:1076404)
w (6.9289253a.chunk.js:2:1076907)
value (6.9289253a.chunk.js:2:1077460)
b (6.9289253a.chunk.js:2:1076404)
w (6.9289253a.chunk.js:2:1076907)
value (6.9289253a.chunk.js:2:1077460)
(anonymous function) (6.9289253a.chunk.js:2:353163)
(anonymous function)
[Error] Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating 'i.get')
dispatchException (6.9289253a.chunk.js:2:1033029)
(anonymous function) (6.9289253a.chunk.js:2:1029238)
r (6.9289253a.chunk.js:2:58397)
u (6.9289253a.chunk.js:2:58637)
promiseReactionJob
[Log] [DEBUG] 18:16.913 StorageClass - No plugin found with providerName – "AWSS3" (6.9289253a.chunk.js, line 2)
It seems to point to Storage.get is undefined which is the only Storage feature we are currently using.
This only happened in our production environment, development had no errors, which seems to point to an issue with web pack (this is a create-react-app which is not ejected) tree-shaking or something.
@houmark, can you try after deleting your node_modules to see if it resolves the issue for you?
This first failed in Amplify Console. I can’t control that. I don’t think it’s caching anything but to the best of my knowledge I can’t change anything related to that in Amplify Console.
When I realized this had broken I then did the production build on my local machine with the same error happening. As I mentioned, this did not happen when running locally in development mode where it does not process in web pack.
@houmark, below are the steps I tried to reproduce this issue
# Create a new react-app
$ npx create-react-app storagetest && cd storagetest
# Add amplify configuration
$ amplify init
$ amplify add storage
<Answer amplify cli questions and add default auth configuration and guest and auth users for storage>
$ amplify push
# Add amplify
$ yarn add @aws-amplify/storage @aws-amplify/auth
# Add code to call Storage.get() in App.js
import React from "react";
import logo from "./logo.svg";
import "./App.css";
import Storage from "@aws-amplify/storage";
import Auth from "@aws-amplify/auth";
import awsconfig from "./aws-exports";
Storage.configure(awsconfig);
Auth.configure(awsconfig);
async function getStorage(file) {
console.log(
"getSignedUrl result ",
await Storage.get("filename", { expires: 1500 })
);
}
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<button onClick={getStorage}>getStorage</button>
</header>
</div>
);
}
export default App;
# Build a production build
$ yarn build #(I tried yarn build --prod as well)
# Run the app
$ serve -s build -p 3000
Using the above steps, I can see correct results in the browser console when I click the button getStorage.
I might be missing something specific to your setup. Can you help with providing a reproduction repo which we can clone and see the error? (Or at a minimum repro steps that allow us to reproduce)
Thanks for your effort @Amplifiyer — what does your aws-exports.js show in relation to S3? From reading the code that fails, I think it's not finding the data in mine which may be the CLI not having generated it correctly, but I am really not sure on this one.
As mentioned earlier, I am not able clear caches on Amplify Console and it happens both there and in my local app when I run npm run build. It is working perfectly in 2.x though.
I'm doing none of this:
import Storage from "@aws-amplify/storage";
import Auth from "@aws-amplify/auth";
import awsconfig from "./aws-exports";
Storage.configure(awsconfig);
Auth.configure(awsconfig);
I'm doing it like this:
App.js:
import Amplify, { Auth, Hub, API, graphqlOperation } from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
And then in my local component where I'm using Storage, I'm just importing Storage (but not from @aws-amplify/storage):
import { API, graphqlOperation, Storage } from 'aws-amplify';
I do not have Auth.configure.
I will try out your code applied to my setup to see if it makes any difference.
@houmark, your aws_exports is perfectly fine. However, I think I can guess the root cause now. In your current setup, can you call Storage.configure(aws_exports) before using Storage APIs.
It's because the instantiation of the S3 provider is in the configure method
https://github.com/aws-amplify/amplify-js/blob/master/packages/storage/src/Storage.ts#L156-L158
And with the modularization update, Amplify.configure() only configures the categories you have imported at that time (in contrast to instantiate all categories when you do Amplify.configure()) to help with tree shaking and bundle size improvements.
If this is the root cause, it's a great feedback for us to update our docs about this "breaking change" which can cause similar issues to other customers.
I will try, and report back in a bit! Thanks!
Happy to report, that fixed it. So yes, this should be added to breaking change. 2 lines needed, import the exports file and Storage.configure.
Thanks for your quick help!
Ooops, hang on... I did not do my production build yet, I jumped it, will test and report back in a moment.
It does work on my production build also, sorry about that.
On a related note to that, it is weird that locally when not creating the production build it did work, but that may be npm cache?
Also, a nice side effect of this major version update is that my main chunk was shrunk and is now HALF the size (was ~750kb and it's now ~367kb) as it seems web pack is now able to proper tree shake this package. I always had named imports, but for some reason it may have imported the entire package.
Thanks again!
Thanks @houmark for confirming.
On a related note to that, it is weird that locally when not creating the production build it did work, but that may be npm cache?
This is because tree shaking is activated only in prod builds (typical create-react-app webpack configs) and local development builds do not have any tree shaking applied, so if you have add aws-amplify package, you have all the categories in your local development "build"
Also, a nice side effect of this major version update is that my main chunk was shrunk and is now HALF the size (was ~750kb and it's now ~367kb) as it seems web pack is now able to proper tree shake this package. I always had named imports, but for some reason it may have imported the entire package.
Happy to hear that, there are many changes beneath the hood which will influence your bundle size, biggest of them is underlying aws-sdk which is now modularized as well!
Spamming on here.
I searched our source code and I am now wondering if I also need to do Auth.configure to ensure it works. We have custom made Authentication components, but we are using Auth.signOut() and it does seem like it works without any modification, but is the correct use now to configure each feature / API before using it?
This is because tree shaking is activated only in prod builds (typical create-react-app webpack configs) and local development builds do not have any tree shaking applied, so if you have add aws-amplify package, you have all the categories in your local development "build"
Yes, that was my thought also right after sending my last message.
May I suggest adding a better console output message when Storage fails due to this error and tell the dev to maybe ensure doing Storage.configure (of course for all features / APIs).
You need to ensure to do it once before each usage to correctly bootstrap it. All amplify categories are supposed to be singletons and do not need multiple configure/instantiations. The only breaking change(and what users need to ensure) is that Amplify.configure() will only configure the categories that you have imported in that file.
You need to ensure to do it once before each usage to correctly bootstrap it. All amplify categories are supposed to be singletons and do not need multiple configure/instantiations. The only breaking change(and what users need to ensure) is that
Amplify.configure()will only configure the categories that you have imported in that file.
So it should not hurt to do Auth.configure and is best practice as I understand it.
This is because tree shaking is activated only in prod builds (typical create-react-app webpack configs) and local development builds do not have any tree shaking applied, so if you have add aws-amplify package, you have all the categories in your local development "build"
Yes, that was my thought also right after sending my last message.
May I suggest adding a better console output message when Storage fails due to this error and tell the dev to maybe ensure doing
Storage.configure(of course for all features / APIs).
@swaminator @litwicki FYI
Resolving this. Will be updating our docs for V3 breaking changes.
Most helpful comment
It does work on my production build also, sorry about that.
On a related note to that, it is weird that locally when not creating the production build it did work, but that may be npm cache?
Also, a nice side effect of this major version update is that my main chunk was shrunk and is now HALF the size (was ~750kb and it's now ~367kb) as it seems web pack is now able to proper tree shake this package. I always had named imports, but for some reason it may have imported the entire package.
Thanks again!