You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio字符串赋值失效,Firebase双文件上传链接获取问题

问题:Firebase上传MP3与封面后,封面链接无法写入实时数据库

实现流程

  • 选择本地MP3 Uri
  • 将MP3上传至Firebase Storage
  • 提取MP3元数据(名称、艺术家、专辑封面)
  • 上传专辑封面至Firebase Storage
  • 在Firebase实时数据库创建包含MP3下载链接、封面下载链接、名称、艺术家的Song对象

异常现象

在MP3上传成功的回调中提取元数据并上传封面,封面上传成功后将下载链接赋值给变量,但后续创建Song对象并写入数据库时,该变量始终为空。尝试过静态、非静态、局部变量等多种声明方式,问题依旧。


问题根源

Firebase的putBytes()(封面上传)和getDownloadUrl()都是异步执行的非阻塞操作。当前代码中,触发封面上传后立刻执行创建Song对象的逻辑,此时封面上传的异步任务还未完成,变量还没被赋值,导致写入数据库时封面链接为空。封面上传成功的回调会在主线程空闲时才执行,此时数据库写入操作早已完成。


修复代码

将创建Song对象并写入数据库的逻辑,移至封面上传成功的回调内部,同时优化getDownloadUrl()的处理(避免用while循环阻塞线程,改用回调链式调用):

private void uploadFile() {
    if (!filename.getText().toString().equals("") && imgView != null) {
        StorageReference mp3ref = mp3StorageRef.child(SongName.getText().toString().trim() + "_" + System.currentTimeMillis() + "." + getFileExtension(Mp3_uri));

        mp3ref.putFile(Mp3_uri)
                .addOnSuccessListener(taskSnapshot -> {
                    Handler handler = new Handler();
                    handler.postDelayed(() -> progressBar.setProgress(0), 500);

                    MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
                    mediaMetadataRetriever.setDataSource(getContext(), Mp3_uri);

                    String name = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
                    String artist = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
                    byte[] art = mediaMetadataRetriever.getEmbeddedPicture();

                    // 获取MP3的下载链接
                    taskSnapshot.getStorage().getDownloadUrl()
                            .addOnSuccessListener(mp3DownloadUrl -> {
                                // 上传封面
                                StorageReference cover = coverStorageRef.child("cover_" + name + "_" + System.currentTimeMillis() + ".jpg");
                                cover.putBytes(art)
                                        .addOnSuccessListener(coverTaskSnapshot -> {
                                            // 获取封面下载链接
                                            coverTaskSnapshot.getStorage().getDownloadUrl()
                                                    .addOnSuccessListener(coverDownloadUrl -> {
                                                        // 两个链接都获取到后,创建Song对象并写入数据库
                                                        Song song = new Song(name, artist, coverDownloadUrl.toString(), mp3DownloadUrl.toString());
                                                        String uploadId = databaseReference.push().getKey();
                                                        databaseReference.child(uploadId).setValue(song);
                                                        Toast.makeText(getContext(), "Upload Success", Toast.LENGTH_SHORT).show();
                                                    });
                                        })
                                        .addOnFailureListener(e -> Toast.makeText(getContext(), "Cover Upload Failed", Toast.LENGTH_SHORT).show());
                            })
                            .addOnFailureListener(e -> Toast.makeText(getContext(), "Failed to get MP3 URL", Toast.LENGTH_SHORT).show());
                })
                .addOnFailureListener(e -> Toast.makeText(getContext(), "MP3 Upload Failed", Toast.LENGTH_SHORT).show())
                .addOnProgressListener(snapshot -> {
                    double progress = (100.0 * snapshot.getBytesTransferred() / snapshot.getTotalByteCount());
                    progressBar.setProgress((int) progress);
                });
    } else {
        Toast.makeText(getContext(), "No File Selected", Toast.LENGTH_SHORT).show();
    }
}

内容的提问来源于stack exchange,提问作者Kaiser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:45:36