Как мне динамически создать ссылку на хранилище Firebase на основе предыдущего значения ссылки? - PullRequest
0 голосов
/ 11 июля 2020

Вот краткий обзор процесса, в котором мне нужна помощь:

  1. Клиент загружает изображения в хранилище Firebase по адресу users / displayName / uid / - этот шаг понятен и выполнен. По этому поводу помощь не требуется.

  2. Затем клиент нажимает кнопку «запросить цитату», которая сохраняет URL-адреса изображений (тех, которые были загружены в хранилище на шаге 1) в Firebase Firestore - этот шаг понятен и выполнен. В этом случае помощь не требуется.

  3. После сохранения URL-адресов в Firestore я хочу, чтобы эти изображения из шага 1 были перемещены в том же ведре хранилища в users / displayName / uid / order1. Итак, в основном, от пользователей / displayName / uid / к пользователям / displayName / uid / order1. - Мне нужна помощь с написанием правильного кода Javascript для этого действия. Я попробовал приведенный ниже фрагмент кода, но он, похоже, не работает, я не уверен, что не так.

  4. В какой-то момент в будущем тому же клиенту потребуется загрузить больше изображений, таким образом повторяя первые 3 шага выше. Однако на 3-м шаге мне нужно, чтобы его изображения были перемещены из users / displayName / uid / в users / displayName / uid / order2. Проблема заключается в том, что я не знаю, как отобразить последнюю часть каталога как order2, а не как order1, как на 3-м шаге. Число после «заказа» в основном должно увеличиваться каждый раз, когда клиент повторяет шаги. Я понятия не имею, как написать для этого правильный код. Пожалуйста, помогите.

Если это поможет, вот мои функции, которые загружают изображения в Firebase Storage и Firebase Firestore:

// Upload to Storage

    handleUpload = () => {

        this.state.files.forEach((file) => {
            const storageRef = firebase.storage().ref(`users/${this.state.displayName}/${this.state.uid}/${file.name}`);
            var task = storageRef.put(file)


            // Progress

            task.on("state_changed", snapshot => {

                const progress = Math.round(
                    (snapshot.bytesTransferred / snapshot.totalBytes) * 100
                );
                this.setState({ progress });
            },


                // Error

                error => {
                    console.log(error);
                },


                // Additional function to update state with all files uploaded

                () => {
                    firebase.storage()
                        .ref(`users/${this.state.displayName}/${this.state.uid}`)
                        .child(file.name)
                        .getDownloadURL()
                        .then(url => {
                            this.setState(state => {
                                const urls = [...state.urls, url];
                                return {
                                    urls
                                };
                            });
                        });


                    // Empty file upload

                    this.setState({ progress: 0 })
                    this.setState({ files: [] })
                }
            );

        })


    };


// Saving to Firestore - PRESS GET A QUOTE TO ACTIVATE

    async saveToFirestore() {

        // Getting it all from storage first        
        const listRef = firebase.storage().ref(`users/${this.state.displayName}/${this.state.uid}`)

        const res = await listRef.listAll()
        const urlPromises = res.items.map((itemRef) => {
            return itemRef.getDownloadURL()
        })
        const urls = await Promise.all(urlPromises)


        // Then, we save it all to Firestore
        firebase.firestore().collection('Documents/').doc(this.state.displayName).set({
            documents: urls,
            quote: 'pending',
            name: this.state.displayName,
            email: this.state.email,
            emailVerified: this.state.emailVerified,
            createdAt: firebase.firestore.FieldValue.serverTimestamp(),
            userId: this.state.uid
        })
            .then(() => {

                const listRef = firebase.storage().ref(`users/${this.state.displayName}/${this.state.uid}`)

                listRef.listAll().then((res) => {

                    console.log(res)

                    res.items.forEach(function (item) {

                        console.log(item)

                        firebase.storage().ref(`users/${this.state.displayName}/${this.state.uid}/order1/${item.name}`).put(item);
                    });
                }).catch(function (error) {
                    // Uh-oh, an error occurred!
                });



                this.setState({ quote: "pending" })

                firebase.firestore().collection('Documents/').doc(this.state.displayName).get().then((doc) => {

                    if (doc.exists) {
                        doc.data().documents.forEach(url => {
                            this.setState(state => {
                                const documents = [...state.documents, url];
                                return {
                                    documents
                                };
                            });
                        })


                        this.setState({ createdAt: doc.data().createdAt.toDate().toString() })

                    } else {
                        // doc.data() will be undefined in this case
                        console.log("No such document!");
                    }
                }).catch(function (error) {
                    console.log("Error getting document:", error);
                });
            })
            .catch((error) => {
                console.error("Error writing document: ", error);
            });

    }

Пожалуйста, дайте мне знать, если что-то еще необходимо.

Большое спасибо!

1 Ответ

0 голосов
/ 12 июля 2020

Насколько я могу судить, ваш вопрос состоит из двух частей:

  1. Определите папку для следующего заказа
  2. Запишите все файлы из root в этот папка

Я сосредоточусь на первом шаге в этом ответе.

Определите папку для следующего заказа

Чтобы определить следующую order? папку, мы получим список всех файлов / папок из хранилища, а затем отфильтруем их, чтобы определить там наибольшее число:

var ref = firebase.storage().ref("62849565");

ref.listAll().then(function(res) {
  // Determine the next order folder
  const orderFolders = res.prefixes.filter((folder) => folder.name.match(/^order(\d+)$/));
  let highestOrderNumber = 0;
  orderFolders.forEach((folder) => {
    const match = folder.name.match(/^order(\d+)$/);
    const number = parseInt(match[1]);
    if (number > highestOrderNumber) {
      highestOrderNumber = number;
    }
  })
  const nextOrderFolderPrefix = "order" + (highestOrderNumber+1);

  // Move the files from the root to the new folder
  res.items.forEach(function(itemRef) {
    // TODO: read file from root and write it to the next order folder
  });
}).catch(function(error) {
  console.error(error);
});

(также см. jsbin , где я создал / протестировал этот код)

В приведенном выше примере:

  1. res.prefixes.filter((folder) => folder.name.match(/^order(\d+)$/)) гарантирует, что мы будем рассматривать только папки, соответствующие шаблону именования order1.
  2. Затем мы l oop по папкам, чтобы найти наибольший номер.
  3. Мы определяем путь для следующей папки.

Записать все файлы из root в новую папку

TODO в этом коде означает перемещение фактического файла. В Cloud Storage (или его Firebase SDK) нет операций по перемещению файла . Таким образом, вам нужно будет выполнить последовательность чтения файла, записать его в новое место и удалить из исходного местоположения. Я рекомендую немного поискать, поскольку я почти уверен, что об этом уже спрашивали раньше.

...