Skip to content

Commit 5ba5def

Browse files
authored
Merge pull request #740 from invertase/feat/storage-ts
Migrate storage example to Modular (TS) API
2 parents 33803eb + 0053627 commit 5ba5def

14 files changed

Lines changed: 16958 additions & 5684 deletions

.eslintrc.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"parserOptions": {
3-
"ecmaVersion": 2017
3+
"ecmaVersion": 2017,
4+
"sourceType": "module"
45
},
56
"env": {
67
"browser": true
@@ -39,4 +40,4 @@
3940
"firebase": true,
4041
"Promise": true
4142
}
42-
}
43+
}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
**/*.bak
66
.idea
77
.firebaserc
8+
dist/
9+
**/ui-debug.log

package-lock.json

Lines changed: 15220 additions & 5586 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

storage/.prettierrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"singleQuote": true
3+
}

storage/config.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export const firebaseConfig = {
2+
// Your web app's Firebase configuration here
3+
// See https://firebase.google.com/docs/web/setup#add-sdks-initialize
4+
apiKey: 'API_KEY',
5+
authDomain: 'PROJECT_ID.firebaseapp.com',
6+
databaseURL: 'https://PROJECT_ID.firebaseio.com',
7+
projectId: 'PROJECT_ID',
8+
storageBucket: 'PROJECT_ID.appspot.com',
9+
messagingSenderId: 'SENDER_ID',
10+
appId: 'APP_ID',
11+
measurementId: 'G-MEASUREMENT_ID',
12+
};

storage/firebase.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
11
{
22
"hosting": {
3-
"public": "./",
3+
"public": "dist",
44
"ignore": [
55
"firebase.json",
66
"**/.*",
77
"**/node_modules/**"
88
]
9+
},
10+
"storage": {
11+
"rules": "storage.rules"
12+
},
13+
"emulators": {
14+
"auth": {
15+
"port": 9099
16+
},
17+
"storage": {
18+
"port": 9199
19+
},
20+
"ui": {
21+
"enabled": true,
22+
"port": 4000
23+
},
24+
"singleProjectMode": true
925
}
1026
}

storage/index.html

Lines changed: 58 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!DOCTYPE html>
1+
<!doctype html>
22
<!--
33
Copyright (c) 2016 Google Inc.
44
@@ -15,105 +15,68 @@
1515
limitations under the License.
1616
-->
1717
<html>
18-
<head>
19-
<meta charset=utf-8 />
20-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
21-
<title>Firebase SDK for Cloud Storage Quickstart</title>
18+
<head>
19+
<meta charset="utf-8" />
20+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
21+
<title>Firebase SDK for Cloud Storage Quickstart</title>
2222

23-
<!-- Material Design Theming -->
24-
<link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.orange-indigo.min.css">
25-
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
26-
<script defer src="https://code.getmdl.io/1.1.3/material.min.js"></script>
23+
<!-- Material Design Theming -->
24+
<link
25+
rel="stylesheet"
26+
href="https://code.getmdl.io/1.1.3/material.orange-indigo.min.css"
27+
/>
28+
<link
29+
rel="stylesheet"
30+
href="https://fonts.googleapis.com/icon?family=Material+Icons"
31+
/>
32+
<script defer src="https://code.getmdl.io/1.1.3/material.min.js"></script>
2733

28-
<link rel="stylesheet" href="main.css">
29-
</head>
30-
<body>
31-
<div class="demo-layout mdl-layout mdl-js-layout mdl-layout--fixed-header">
32-
33-
<!-- Header section containing title -->
34-
<header class="mdl-layout__header mdl-color-text--white mdl-color--light-blue-700">
35-
<div class="mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-grid">
36-
<div class="mdl-layout__header-row mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--8-col-desktop">
37-
<h3>Firebase SDK for Cloud Storage Quickstart</h3>
34+
<link rel="stylesheet" href="main.css" />
35+
</head>
36+
<body>
37+
<div class="demo-layout mdl-layout mdl-js-layout mdl-layout--fixed-header">
38+
<!-- Header section containing title -->
39+
<header
40+
class="mdl-layout__header mdl-color-text--white mdl-color--light-blue-700"
41+
>
42+
<div class="mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-grid">
43+
<div
44+
class="mdl-layout__header-row mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--8-col-desktop"
45+
>
46+
<h3>Firebase SDK for Cloud Storage Quickstart</h3>
47+
</div>
3848
</div>
39-
</div>
40-
</header>
41-
42-
<main class="mdl-layout__content mdl-color--grey-100">
43-
<div class="mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-grid">
49+
</header>
4450

45-
<!-- Container for the demo -->
46-
<div class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--12-col-desktop">
47-
<div class="mdl-card__title mdl-color--light-blue-600 mdl-color-text--white">
48-
<h2 class="mdl-card__title-text">Upload a file</h2>
49-
</div>
50-
<div class="mdl-card__supporting-text mdl-color-text--grey-600" id="messagesDiv">
51-
<p>Select a file below. When it is uploaded, a link will be displayed to the uploaded file.</p>
52-
<h6>Choose File</h6>
53-
<input type="file" id="file" name="file"/>
54-
<h6>File URL:</h6>
55-
<span id="linkbox"></span>
51+
<main class="mdl-layout__content mdl-color--grey-100">
52+
<div class="mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-grid">
53+
<!-- Container for the demo -->
54+
<div
55+
class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--12-col-tablet mdl-cell--12-col-desktop"
56+
>
57+
<div
58+
class="mdl-card__title mdl-color--light-blue-600 mdl-color-text--white"
59+
>
60+
<h2 class="mdl-card__title-text">Upload a file</h2>
61+
</div>
62+
<div
63+
class="mdl-card__supporting-text mdl-color-text--grey-600"
64+
id="messagesDiv"
65+
>
66+
<p>
67+
Select a file below. When it is uploaded, a link will be
68+
displayed to the uploaded file.
69+
</p>
70+
<h6>Choose File</h6>
71+
<input type="file" id="file" name="file" />
72+
<h6>File URL:</h6>
73+
<span id="linkbox"></span>
74+
</div>
5675
</div>
5776
</div>
58-
</div>
59-
</main>
60-
</div>
61-
62-
<!-- Import and configure the Firebase SDK -->
63-
<!-- These scripts are made available when the app is served or deployed on Firebase Hosting -->
64-
<!-- If you do not serve/host your project using Firebase Hosting see https://firebase.google.com/docs/web/setup -->
65-
<script src="/__/firebase/9.22.1/firebase-app-compat.js"></script>
66-
<script src="/__/firebase/9.22.1/firebase-auth-compat.js"></script>
67-
<script src="/__/firebase/9.22.1/firebase-storage-compat.js"></script>
68-
<script src="/__/firebase/init.js"></script>
69-
70-
<script>
71-
var auth = firebase.auth();
72-
var storageRef = firebase.storage().ref();
73-
74-
function handleFileSelect(evt) {
75-
evt.stopPropagation();
76-
evt.preventDefault();
77-
var file = evt.target.files[0];
78-
79-
var metadata = {
80-
'contentType': file.type
81-
};
82-
83-
// Push to child path.
84-
storageRef.child('images/' + file.name).put(file, metadata).then(function(snapshot) {
85-
console.log('Uploaded', snapshot.totalBytes, 'bytes.');
86-
console.log('File metadata:', snapshot.metadata);
87-
// Let's get a download URL for the file.
88-
snapshot.ref.getDownloadURL().then(function(url) {
89-
console.log('File available at', url);
90-
document.getElementById('linkbox').innerHTML = '<a href="' + url + '">Click For File</a>';
91-
});
92-
}).catch(function(error) {
93-
console.error('Upload failed:', error);
94-
});
95-
}
96-
97-
window.onload = function() {
98-
document.getElementById('file').addEventListener('change', handleFileSelect, false);
99-
document.getElementById('file').disabled = true;
77+
</main>
78+
</div>
10079

101-
auth.onAuthStateChanged(function(user) {
102-
if (user) {
103-
console.log('Anonymous user signed-in.', user);
104-
document.getElementById('file').disabled = false;
105-
} else {
106-
console.log('There was no anonymous session. Creating a new anonymous user.');
107-
// Sign the user in anonymously since accessing Storage requires the user to be authorized.
108-
auth.signInAnonymously().catch(function(error) {
109-
if (error.code === 'auth/operation-not-allowed') {
110-
window.alert('Anonymous Sign-in failed. Please make sure that you have enabled anonymous ' +
111-
'sign-in on your Firebase project.');
112-
}
113-
});
114-
}
115-
});
116-
}
117-
</script>
118-
</body>
80+
<script type="module" src="main.ts"></script>
81+
</body>
11982
</html>

storage/main.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { initializeApp } from 'firebase/app';
2+
import { getAuth, connectAuthEmulator, signInAnonymously } from 'firebase/auth';
3+
import {
4+
connectStorageEmulator,
5+
getStorage,
6+
ref,
7+
uploadBytes,
8+
getDownloadURL,
9+
} from 'firebase/storage';
10+
import { firebaseConfig } from './config';
11+
12+
const fileInput = document.getElementById('file') as HTMLInputElement;
13+
const linkBox = document.getElementById('linkbox') as HTMLDivElement;
14+
15+
initializeApp(firebaseConfig);
16+
17+
const auth = getAuth();
18+
const storage = getStorage();
19+
20+
// Locally, we use the firebase emulators.
21+
if (window.location.hostname === 'localhost') {
22+
connectAuthEmulator(auth, 'http://127.0.0.1:9099');
23+
connectStorageEmulator(storage, '127.0.0.1', 9199);
24+
}
25+
26+
const storageRef = ref(storage);
27+
28+
function handleFileSelect(e: Event) {
29+
e.stopPropagation();
30+
e.preventDefault();
31+
32+
const target = e.target as HTMLInputElement | null;
33+
const files = target?.files;
34+
if (!target || !files) {
35+
return;
36+
}
37+
38+
const file = files[0];
39+
40+
// Push to child path.
41+
uploadBytes(ref(storageRef, 'images/' + file.name), file)
42+
.then(function (snapshot) {
43+
console.log('Uploaded', snapshot.metadata.size, 'bytes.');
44+
console.log('File metadata:', snapshot.metadata);
45+
// Let's get a download URL for the file.
46+
getDownloadURL(snapshot.ref).then(function (url) {
47+
console.log('File available at', url);
48+
linkBox.innerHTML = '<a href="' + url + '">Click For File</a>';
49+
});
50+
})
51+
.catch(function (error) {
52+
console.error('Upload failed:', error);
53+
});
54+
}
55+
56+
fileInput.addEventListener('change', handleFileSelect, false);
57+
fileInput.disabled = true;
58+
59+
auth.onAuthStateChanged(function (user) {
60+
if (user) {
61+
console.log('Anonymous user signed-in.', user);
62+
fileInput.disabled = false;
63+
} else {
64+
console.log(
65+
'There was no anonymous session. Creating a new anonymous user.',
66+
);
67+
// Sign the user in anonymously since accessing Storage requires the user to be authorized.
68+
signInAnonymously(auth).catch(function (error) {
69+
if (error.code === 'auth/operation-not-allowed') {
70+
window.alert(
71+
'Anonymous Sign-in failed. Please make sure that you have enabled anonymous ' +
72+
'sign-in on your Firebase project.',
73+
);
74+
}
75+
});
76+
}
77+
});

0 commit comments

Comments
 (0)