How Can I Quickly Integrate Cloud Storage of AppGallery Connect into a Web Project

HUAWEI AppGallery Connect Cloud Storage provides maintenance-free cloud storage functions.

Recently, the Cloud Storage JavaScript SDK for web has been released. I’ve been using it for a while.

1. Configuring Environment and Version Information

Environment:Window-Node -v14.15.0、npm v6.14.8、Intellij + Vue

Test Device:PC-Chrome

SDK version: “@agconnect/cloudstorage”: “1.0.0-beta3”

SDK integration command: npm install — save @agconnect/cloudstorage

2. Enabling and Configuring Cloud Storage in AppGallery Connect

https://developer.huawei.com/consumer/en/doc/development/AppGallery-connect-Guides/agc-cloudstorage-apply

To enable Cloud Storage, you need to create an app first and add it to a project, or select an app from the project list on the My projects page in AppGallery Connect.

Under the project, go to Build > Cloud Storage, and click Enable now.

Configure a storage instance as required.

Define security rules. In this example, the default rules are used.

Note: By default, only authorized users have read and write permissions.

3. Installing the Development Environment

1. Install IntelliJ IDEA.

Make sure to download IntelliJ IDEA Ultimate, which is used for web.

2. Create a Vue.js project.

3. After the compilation, the following files are generated.

4. Integrating the SDK

npm install --save @agconnect/cloudstorage

When you install the Cloud Storage JavaScript SDK, a matching AppGallery Connect SDK will be automatically installed.

2. Create the agConnectConfig.js file in the app-level src directory and copy all content under Project settings > General information > App information > SDK Code Snippet to the agConnectConfig.js configuration file.

Don’t forget to add the export parameter.

3. Run the npm install command in the project directory to install the dependencies in package.json.

5. Developing Functions

a) Creating a Page Layout

<div class = "hello">
<div v-show="!isLogin">
<el-button type="primary" @click="signInAnonymously">Login</el-button>
</div>
<div v-show="isLogin" style="max-width:1600px;margin:auto;">
<h1>AGCCloudStorageDemo</h1>
<div style="display:flex;margin-bottom:30px;">
<el-button type="primary" size="medium" @click="getFileList('')">Get FileList</el-button>
<el-button type="primary" size="medium" @click="getFileListAll('')">
Get FileList All
</el-button>
<el-button type="primary" size="medium" @click="uploadString">
Upload String
</el-button>
<el-upload action :on-change="uploadFile" :auto-upload="false">
<el-button type="primary" size="medium" style="width: 100%;margin-left:10px;">Upload File</el-button>
</el-upload>
</div>
<el-table
ref="multipleTable"
border
size="medium"
:data="list">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column width="80px" label="index">
<template v-slot="scope">
{{ scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column width="100px" label="type">
<template v-slot="scope">
{{ scope.row.isFile ? 'file' : 'directory' }}
</template>
</el-table-column>
<el-table-column
width="150px"
label="name"
prop="name"
show-overflow-tooltip>
</el-table-column>
<el-table-column label="operation">
<template v-slot="scope">
<el-button
v-if="!scope.row.isFile"
type="success"
size="medium"
@click="getFileList(scope.row)"
>
Get FileList
</el-button>
<el-button
v-if="!scope.row.isFile"
type="success"
size="medium"
@click="getFileListAll(scope.row)"
>
Get FileList All
</el-button>
<el-button
v-if="scope.row.isFile"
type="success"
size="medium"
@click="downloadFile(scope.row)"
>
Download File
</el-button>
<el-button
v-if="scope.row.isFile"
type="success"
size="medium"
@click="getFileMetadata(scope.row)"
>
Get FileMetadata
</el-button>
<el-button
v-if="scope.row.isFile"
type="success"
size="medium"
@click="updateFileMetadata(scope.row)"
>
Update FileMetadata
</el-button>
<el-button v-if="scope.row.isFile" type="danger" size="medium" @click="deleteFile(scope.row)">
Delete File
</el-button>
<el-button type="success" size="medium" @click="toString(scope.row)">
To String
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>

b) Adding Configuration Dependencies and Initializing the SDK

import agconnect from "@agconnect/api";
import "@agconnect/instance";
import "@agconnect/auth";
import "@agconnect/cloudstorage";

2. Initialize the AppGallery Connect SDK.

import { agConnectConfig } from "../agConnectConfig";
const config = agConnectConfig

c) Prerequisites: Adding the data and methods Objects

1. Add the data object and the following code:

data(){
return {
list:[],
isLogin:false,
ref:{}
}
},

2. Add the mounted object and the following code:

mounted(){
agconnect.instance().configInstance(config)
},

3. Add the methods object and the signInAnonymously method:

methods:{
async signInAnonymously () {
agconnect
.auth()
.signInAnonymously()
.then(() => {
alert('login successfully!')
this.isLogin = true
this.ref = agconnect.cloudStorage().storageReference()
})
.catch(() => {
return Promise.reject('sign in anonymously failed')
})
},}

d) Uploading a File

uploadFile(file) {
const path = 'jssdk/' + file.name
const metadata = {
cacheControl: 'helloworld',
contentDisposition: 'helloworld',
contentEncoding: 'helloworld',
contentLanguage: 'helloworld',
contentType: 'helloworld',
customMetadata: {
hello: 'kitty'
}
}
var uploadTask = this.ref.child(path).put(file.raw, metadata)
this.printUploadPercent(uploadTask)
},
printUploadPercent (uploadTask) {
uploadTask.on('state_changed', function (snapshot) {
if(!snapshot){
console.log('Upload Result is null')
return;
}
if(snapshot.totalByteCount == 0){
console.log('Upload File is empty')
return;
}
var progress = (snapshot.bytesTransferred / snapshot.totalByteCount) * 100
console.log('Upload is ' + progress.toFixed(1) + '% done')
switch (snapshot.state) {
case 'paused':
console.log('Upload is paused')
break
case 'running':
console.log('Upload is running')
break
case 'success':
console.log('Upload is success')
break
case 'canceled':
console.log('Upload is canceled')
break
case 'error':
console.log('Upload is error')
break
}
}, function (snapshot) {
switch (snapshot.state) {
case 'paused':
console.log('Upload is paused')
break
case 'running':
console.log('Upload is running')
break
case 'success':
console.log('Upload is success')
break
case 'canceled':
console.log('Upload is canceled')
break
case 'error':
console.log('Upload is error')
break
}
}, function () {
console.log('Upload is success')
})
},

e) Downloading a File

downloadFile(row) {
const child = this.ref.child(row.path)
child.getDownloadURL().then(function (downloadURL) {
alert(downloadURL)
console.log(downloadURL)
})
},

f) Listing Files

getFileList(row) {
var path = row && row.path ? row.path : '';
const child = this.ref.child(path)
child.list({ maxResults: 5 }).then((res) => {
this.list = [...res.dirList.map(item => { item.isFile = false; item.select = false; return item }), ...res.fileList.map(item => { item.isFile = true; item.select = false; return item })]
this.nextMarker = res.pageMarker
console.log(this.list)
}).catch(err => {
console.log(err)
})
},
getFileListAll(row) {
const child = this.ref.child(row && row.path ? row.path : '')
child.listAll()
.then((res) => {
console.log('res', res)
this.list = [...res.dirList.map(item => { item.isFile = false; item.select = false; return item }), ...res.fileList.map(item => { item.isFile = true; item.select = false; return item })]
})
.catch((err) => {
console.log(err)
})
},

6. Verifying Functions

1. Prerequisites for Running the Web Environment

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

2. Run the following command in the project directory to install the element-ui dependency:

npm install element-ui -S

After the installation is complete, the following code is generated in the package.json file.

3. In the app.vue file, create a page.

In the template element, set the page you created just now as the default page.

<template>
<div id="app">
<Page />
</div>
</template>

In the script element, import and modify the default page.

<script>
import Page from './components/Page.vue'

export default {
name: 'App',
components: {
Page
}
}
</script>

The modification result is as follows.

2. Running the Project

3. Configuring a CORS Request

For details about the integration of a Node.js project, see my previous post: How Can I Quickly Integrate Cloud Storage of AppGallery Connect into a Node.js Project?

In the Node.js code, use the setCorsConfiguration method to configure CORS parameters. Sample code:

crossIP();
function crossIP() {
const storage = new StorageManagement();
const bucket = storage.bucket(bucketName);

bucket.setCorsConfiguration();
const config = [{
"origins": ["*"],
"methods": ["GET", "POST", "PUT", "DELETE"],
}];

bucket.setCorsConfiguration(config).then(res =>
console.log('bucket.setCors res: ', res)
).catch(err => {
console.log('bucket.setCors err: ', err)
})
}

4. Signing In on the Web Page

5. Obtaining the File List

6. Uploading a File

Click Get FileList on the right to view the uploaded file.

You can try testing the other functions by yourself.

7. Summary

In addition to file upload, download, and deletion, Cloud Storage also offers functions such as listing files and setting metadata.

Cloud Storage development guide:

https://developer.huawei.com/consumer/en/doc/development/AppGallery-connect-Guides/agc-cloudstorage-introduction

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store