Android Firebase上传图像的URL错误(问题:缺少X-Goog-Upload-Comment标题)

Android Firebase上传图像的URL错误(问题:缺少X-Goog-Upload-Comment标题),android,firebase,firebase-realtime-database,firebase-storage,picasso,Android,Firebase,Firebase Realtime Database,Firebase Storage,Picasso,我正在尝试从Firabase数据库上传和下载图像,该数据库有一个指向Firebase存储的URL链接。问题是奇怪的URL被保存到数据库中(请参阅底部的链接)。我应该怎么做才能获得一个正常的URL,我可以使用do downloand将图像导入我的Android应用程序?提前谢谢你 在这里,我发布了一些我使用的代码: 上载到Firebase数据库和存储: mStorageRef = FirebaseStorage.getInstance().getReference(); mDataBaseRef

我正在尝试从Firabase数据库上传和下载图像,该数据库有一个指向Firebase存储的URL链接。问题是奇怪的URL被保存到数据库中(请参阅底部的链接)。我应该怎么做才能获得一个正常的URL,我可以使用do downloand将图像导入我的Android应用程序?提前谢谢你

在这里,我发布了一些我使用的代码:

上载到Firebase数据库和存储:

mStorageRef = FirebaseStorage.getInstance().getReference();
mDataBaseRef = FirebaseDatabase.getInstance().getReference();

if (mImageUri != null)
{
    final StorageReference fileReference = mStorageRef.child(nameimage + "." + getFileExtension(mImageUri));

    fileReference.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

            Toast.makeText(AddAdvertisement.this, "Upload successful!", Toast.LENGTH_LONG).show();

            Upload upload = new Upload(et_localization, taskSnapshot.getUploadSessionUri().toString());
            String uploadId = mDataBaseRef.push().getKey();
            mDataBaseRef.child(uploadId).setValue(upload);


        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(AddAdvertisement.this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
和毕加索一起检索图像:

@Override
public void onBindViewHolder(@NonNull ImageViewHolder imageViewHolder, int i) {

    Upload uploadCurrent = mUploads.get(i);

    imageViewHolder.textViewName.setText(uploadCurrent.getName());

    Picasso.get().load(uploadCurrent.getUrl()).into(imageViewHolder.imageView);
}
毕加索的作品很好,因为除了形成一个图像,我还从Firebase字符串中获得了一个名称,这是适当下载的。所以,我认为问题在于这个错误的url:

当我尝试输入此链接时,我收到此类错误:


无效的请求。缺少X-Goog-Upload-Command标头。

根据有关UploadTask的官方文档。TaskSnapshot的方法:

返回会话Uri,有效期约为一周,通过将此值传递到
putFile(Uri,StorageMetadata,Uri)
,可用于稍后恢复上载


恐怕这不是您要找的
Uri
。要获得正确的uri,请根据有关UploadTask的官方文档查看我的回答。TaskSnapshot的方法:

返回会话Uri,有效期约为一周,通过将此值传递到
putFile(Uri,StorageMetadata,Uri)
,可用于稍后恢复上载


恐怕这不是您要找的
Uri
。要获得正确的uri,请查看我的答案,您正在将此值写入数据库:

taskSnapshot.getUploadSessionUri().toString()
这是上载会话的URI,您可以使用它在上载中止时恢复上载

由于您希望存储下载URL,因此此调用对于您的原因来说是非常无用的。相反,您应该调用
getDownloadUrl()
以(异步)获取新上载文件的下载URL:

fileReference.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

        Toast.makeText(AddAdvertisement.this, "Upload successful!", Toast.LENGTH_LONG).show();

        fileReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
                String url = uri.toString();
                Upload upload = new Upload(et_localization, url);
                String uploadId = mDataBaseRef.push().getKey();
                mDataBaseRef.child(uploadId).setValue(upload);
            }
        });

    }
})...
fileReference.putFile(mimageri).addOnSuccessListener(新的OnSuccessListener()){
@凌驾
成功时公共无效(UploadTask.TaskSnapshot TaskSnapshot){
Toast.makeText(addAdvertision.this,“上载成功!”,Toast.LENGTH_LONG.show();
fileReference.getDownloadUrl().addOnSuccessListener(新OnSuccessListener()){
@凌驾
成功时的公共无效(Uri){
字符串url=uri.toString();
上传上传=新上传(et_本地化,url);
字符串uploadId=mDataBaseRef.push().getKey();
mDataBaseRef.child(uploadId).setValue(upload);
}
});
}
})...

请注意,Firebase中对此进行了很好的描述,该事件包括使用
continueWithTask
而不是嵌套回调(我在上面做过)来完成相同操作的示例。

您正在将此值写入数据库:

taskSnapshot.getUploadSessionUri().toString()
这是上载会话的URI,您可以使用它在上载中止时恢复上载

由于您希望存储下载URL,因此此调用对于您的原因来说是非常无用的。相反,您应该调用
getDownloadUrl()
以(异步)获取新上载文件的下载URL:

fileReference.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

        Toast.makeText(AddAdvertisement.this, "Upload successful!", Toast.LENGTH_LONG).show();

        fileReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {
                String url = uri.toString();
                Upload upload = new Upload(et_localization, url);
                String uploadId = mDataBaseRef.push().getKey();
                mDataBaseRef.child(uploadId).setValue(upload);
            }
        });

    }
})...
fileReference.putFile(mimageri).addOnSuccessListener(新的OnSuccessListener()){
@凌驾
成功时公共无效(UploadTask.TaskSnapshot TaskSnapshot){
Toast.makeText(addAdvertision.this,“上载成功!”,Toast.LENGTH_LONG.show();
fileReference.getDownloadUrl().addOnSuccessListener(新OnSuccessListener()){
@凌驾
成功时的公共无效(Uri){
字符串url=uri.toString();
上传上传=新上传(et_本地化,url);
字符串uploadId=mDataBaseRef.push().getKey();
mDataBaseRef.child(uploadId).setValue(upload);
}
});
}
})...

请注意,Firebase中对此进行了很好的描述,该事件包括一个示例,通过使用
continueWithTask
而不是嵌套回调(我在上面做过)。

这对我不起作用(使用Expo),但使用XMLHttpRequest却起到了作用。我在这里找到了这个解决方案:

下面是我的代码,以防对您有所帮助

_uploadImageAsync = async (uri) => {
  try {
    const blob = await new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.onload = function () {
        resolve(xhr.response);
      };
      xhr.onerror = function (e) {
        console.log(e);
        reject(new TypeError('Network request failed'));
      };
      xhr.responseType = 'blob';
      xhr.open('GET', uri, true);
      xhr.send(null);
    });

    const ref = firebase
      .storage()
      .ref()
      .child('images/usersPicture/test');
    const snapshot = await ref.put(blob);

    blob.close();

    return await snapshot.ref.getDownloadURL();
  } catch(error) {
    console.log(error)
  }
}

这对我不起作用(使用Expo),但使用XMLHttpRequest起作用。我在这里找到了这个解决方案:

下面是我的代码,以防对您有所帮助

_uploadImageAsync = async (uri) => {
  try {
    const blob = await new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.onload = function () {
        resolve(xhr.response);
      };
      xhr.onerror = function (e) {
        console.log(e);
        reject(new TypeError('Network request failed'));
      };
      xhr.responseType = 'blob';
      xhr.open('GET', uri, true);
      xhr.send(null);
    });

    const ref = firebase
      .storage()
      .ref()
      .child('images/usersPicture/test');
    const snapshot = await ref.put(blob);

    blob.close();

    return await snapshot.ref.getDownloadURL();
  } catch(error) {
    console.log(error)
  }
}
fileReference.putFile(mimageri).addOnSuccessListener(新的OnSuccessListener()){
@凌驾
成功时公共无效(UploadTask.TaskSnapshot TaskSnapshot){
Toast.makeText(addAdvertision.this,“上载成功!”,Toast.LENGTH_LONG.show();
fileReference.getDownloadUrl().addOnSuccessListener(新OnSuccessListener()){
@凌驾
成功时的公共无效(Uri){
//只要做你的任务//像hashmaps一样放入
}
});
}
})
fileReference.putFile(mimageri).addOnSuccessListener(新的OnSuccessListener(){
@凌驾
成功时公共无效(UploadTask.TaskSnapshot TaskSnapshot){
Toast.makeText(addAdvertision.this,“上载成功!”,Toast.LENGTH_LONG.show();
fileReference.getDownloadUrl().addOnSuccessListener(新OnSuccessListener()){
@凌驾
成功时的公共无效(Uri){
//只要做你的任务//像hashmaps一样放入
}
});
}
})

您好,谢谢您的帮助,但是另一个答案完成了工作。您好,谢谢您的帮助,但是另一个答案完成了工作。获取错误getDownloadUrl()在存储桶的根目录下不受支持。这意味着您正在调用
引用的
getDownloadUrl()