首页 > 解决方案 > 我无法使用 Firebase 存储编辑封面图片和个人资料图片。我的程序有什么问题?

问题描述

我在我的项目中添加了用户配置文件页面,即 ProfileFragment.java,它的布局文件是 fragment_profile.xml。我想更新用户信息,如姓名、描述、个人资料图片和封面。我的程序没有错误,名称和描述更新成功但封面和头像没有更新?我的代码有什么问题?

这是我的 ProfileFragment.java

public class ProfileFragment extends Fragment {

    //Log Statment
    private static final String TAG = "ProfileFragment";

    //firebase auth
    FirebaseAuth firebaseAuth;
    FirebaseUser user;
    FirebaseDatabase firebaseDatabase;
    DatabaseReference databaseReference;

    //firabase storage
    StorageReference storageReference;
    //profil resminin ve kapak resminin nerede depolanacağının yolu
    String storagePath = "Users_Profile_Cover_Imgs/";

    //layout views
    ImageView avatar, coverPhoto;
    TextView nameTxt, emailTxt, descTxt;
    FloatingActionButton fab;

    //Progress Dialog
    ProgressDialog pd;

    //permissions
    private static final int CAMERA_REQUESTED_CODE = 100;
    private static final int STORAGE_REQUESTED_CODE = 200;
    private static final int IMAGE_PICK_GALLERY_CODE = 300;
    private static final int IMAGE_PICK_CAMERA_CODE = 400;

    //izinler için gerekli arrayler
    String cameraPermissions[];
    String storagePermissions[];

    //seçilen resmin uri adresi
    Uri image_uri;

    //profil fotografı yoksa kapak fotografımı kontrol et
    String profileORCoverPhoto;



    public ProfileFragment() {
        //boş public constructor gerekli
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view =  inflater.inflate(R.layout.fragment_profile, container, false);

        //init firebase
        firebaseAuth = FirebaseAuth.getInstance();
        user = firebaseAuth.getCurrentUser();
        firebaseDatabase = FirebaseDatabase.getInstance();
        databaseReference = firebaseDatabase.getReference("Users");

        //init layout views

        avatar = view.findViewById(R.id.avatar);
        coverPhoto = view.findViewById(R.id.coverPhoto);
        nameTxt = view.findViewById(R.id.nameTxt);
        emailTxt = view.findViewById(R.id.emailTxt);
        descTxt = view.findViewById(R.id.descTxt);
        fab = view.findViewById(R.id.fab);

        pd = new ProgressDialog(getActivity());

        //izin arrayleri
        cameraPermissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
        storagePermissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};



        /* giriş yapan kullanıcıların bilgilerini email yada uid kullanarak çekmek zorundayız
        Kullanıcı detaylarını email adreslerini kullanarak çekicez
        orderbyChild query kullanarak giriş yapılan email ile email key ini eşleştirerek kullanıcı detaylarına ulaşılıyor
         */
        Query query = databaseReference.orderByChild("email").equalTo(user.getEmail());
        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                //gerekli veriler gelene kadar kontrol et
                for (DataSnapshot ds: snapshot.getChildren()){
                    //verileri almak için
                    String name = ""+ ds.child("name").getValue();
                    String email = ""+ ds.child("email").getValue();
                    String desc = ""+ ds.child("desc").getValue();
                    String image = ""+ ds.child("image").getValue();
                    String cover = ""+ ds.child("cover").getValue();



                    //set data
                    nameTxt.setText(name);
                    emailTxt.setText(email);
                    descTxt.setText(desc);
                    Log.d(TAG, "onDataChange: \nName: "+name+" email: "+ email);


                    try {
                        // resim alınırsa ayarla
                        Picasso.get().load(image).into(avatar);
                    } catch (Exception e){
                        // resim alınırken herangi bir sıkıntı varsa varsayılan olarak ayarla
                        Picasso.get().load(R.drawable.add_photo_foreground).into(avatar);
                    }

                    try {
                        // kapak resimi alınırsa ayarla
                        Picasso.get().load(cover).into(coverPhoto);
                    } catch (Exception e){
                        // kapak resmi alınırken herangi bir sıkıntı varsa varsayılan olarak ayarla
                        Picasso.get().load(R.drawable.default_cover_photo).into(coverPhoto);
                    }
                }
                Log.d(TAG, "onDataChange: Data is empty");

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Log.d(TAG, "onCancelled: "+error);
            }
        });

        //fab button onClick özelliği ekleme
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //edit profile dialog göster
                showEditProfileDialog();
            }
        });

        return view;
    }


    private void requestStoragePermission(){
        //runtime depolama izinleri isteme
        requestPermissions(storagePermissions, STORAGE_REQUESTED_CODE);
    }
    private void requestCameraPermission(){
        //runtime depolama izinleri isteme
        requestPermissions(cameraPermissions, CAMERA_REQUESTED_CODE);
    }

    private boolean checkStoragePermission(){
        //depolama izinlerini kontrol et, etkinse true, değilse false döndür
        boolean result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == (PackageManager.PERMISSION_GRANTED);
        return  result;
    }
    private boolean checkCameraPermission(){
        //depolama izinlerini kontrol et, etkinse true, değilse false döndür
        boolean result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
                == (PackageManager.PERMISSION_GRANTED);

        boolean result1 = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == (PackageManager.PERMISSION_GRANTED);

        return  result && result1;
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //Bu yöntem, kullanıcı izin isteği iletişim kutusundan izin ver veya reddet düğmesine bastığında çağrılır
        //burada izin durumlarını ele alınır(izin verildi ve reddedildi)
        switch (requestCode){
            case CAMERA_REQUESTED_CODE: {
                //camera seçildiğinde önce izin alınmış mı diye kontrol eder
                if (grantResults.length > 0 ){
                    boolean cameraAccepted  = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    boolean writeStorageAccepted  = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                    if(cameraAccepted && writeStorageAccepted){
                        //izinler etkinleştirildi
                        pickFromCamera();
                    }
                    else{
                        //izinler reddedildi
                        Toast.makeText(getActivity(),"Please enable camera && storage permission",Toast.LENGTH_SHORT).show();
                    }
                }
            }
            break;
            //galeri seçildiğinde önce izin alınmış mı diye kontrol eder
            case STORAGE_REQUESTED_CODE: {
                if (grantResults.length > 0 ){
                    boolean cameraAccepted  = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    boolean writeStorageAccepted  = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                    if(writeStorageAccepted){
                        //izinler etkinleştirildi
                        pickFromGallery();
                    }
                    else{
                        //izinler reddedildi
                        Toast.makeText(getActivity(),"Please enable storage permission",Toast.LENGTH_SHORT).show();
                    }
                }
            }
            break;
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        //bu metot camera veya galeri den fotograf seçildikten sonra çağırılıyor
        if (resultCode == RESULT_OK){

            if (requestCode == IMAGE_PICK_GALLERY_CODE){
                //resim geleriden seçildi, resmin uri'sini al
                image_uri = data.getData();

                uploadProfileCoverPhoto(image_uri);
            }
            if (requestCode == IMAGE_PICK_CAMERA_CODE){
                //resim cameradan seçildi, resmin uri'sini al

                uploadProfileCoverPhoto(image_uri);

            }


        }


        super.onActivityResult(requestCode, resultCode, data);
    }



    //Editprofile dialog
    private void showEditProfileDialog() {
        // Profil resmi düzenle, kapak fotografı gösterme, isim düzenleme, açıklama düzenleme
        //Seçenekleri dialogta gösterme
        String options[] = {"Edit Profile Picture", "Edit Cover Photo", "Edit Name", "Edit Description"};

        //alert dialog
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        //başlık
        builder.setTitle("Choose Action");
        //dialog itemlerini ayarlama
        builder.setItems(options, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //dialog itemlere onClick özelliği ekleme
                if (which == 0){
                    //profil düzenleme tıklandı
                    pd.setMessage("Updating Profile Picture");

                    //profil foto mu yoksa kapak foto mu konrol için
                    profileORCoverPhoto = "image"; // profil resmini değiştirirken aynı değerlerin atandığından emin ol

                    showImagePicDialog();

                }
                else if (which == 1){
                    //kapak düzenleme tıklandı
                    pd.setMessage("Updating Cover Picture");

                    //profil foto mu yoksa kapak foto mu konrol için
                    profileORCoverPhoto = "cover"; //kapak resmini değiştirirken aynı değerlerin atandığından emin ol

                    showImagePicDialog();
                }
                else if (which == 2){
                    //isim duzenleme tıklandı
                    pd.setMessage("Updating Name");

                    //veritabanında "name" güncellenmesi için motodun çağırılması
                    showNameDescUpdateDialog("name");

                }
                else if (which == 3){
                    //açıklama düzenleme tıklandı
                    pd.setMessage("Updating Description");

                    showNameDescUpdateDialog("desc");


                }

            }
        });
        //dialog oluşturme ve gösterme
        builder.create().show();
    }


    private void showNameDescUpdateDialog(final String key) {
        //key parametresi "name" ve "desc" değerlerini alıyor

        //custom dialog
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Update "+key); //Update name or Update description..

        //Dialog layoutunu ayarla
        LinearLayout linearLayout = new LinearLayout(getActivity());
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        linearLayout.setPadding(10,10,10,10);
        //editText ekleme
        final EditText editText = new EditText(getActivity());
        editText.setHint("Enter "+ key);
        linearLayout.addView(editText);

        builder.setView(linearLayout);

        //dialog'a update button ekle
        builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //input text from edit text
                String value = editText.getText().toString().trim();
                //kullanıcının bir şeyler girip girmediğini onayla
                if (!TextUtils.isEmpty(value)){
                    pd.show();
                    HashMap<String, Object> result = new HashMap<>();
                    result.put(key, value);
                    databaseReference.child(user.getUid()).updateChildren(result)
                            .addOnSuccessListener(new OnSuccessListener<Void>() {
                                @Override
                                public void onSuccess(Void aVoid) {
                                    //güncellendi, dismiss progress
                                    pd.dismiss();
                                    Toast.makeText(getActivity(),"Updated...",Toast.LENGTH_SHORT).show();

                                }
                            }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            //error mesajı al ve göster, dismiss progress
                            pd.dismiss();
                            Toast.makeText(getActivity(),""+e.getMessage(),Toast.LENGTH_SHORT).show();

                        }
                    });
                }
                else {
                    Toast.makeText(getActivity(), "Please Enter "+key, Toast.LENGTH_SHORT).show();
                }

            }
        });

        //dialog'a cancel button ekle
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();

            }
        });
        //dialog'u oluştur ve göster
        builder.create().show();
    }


    private void showImagePicDialog() {
        //profil resmini cameradan ya da galeriden seçme seçenekleri ekleme
        String options[] = {"Camera", "Gallery"};

        //alert dialog
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        //başlık
        builder.setTitle("Pick Image From");
        //dialog itemlerini ayarlama
        builder.setItems(options, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                //dialog itemlere onClick özelliği ekleme
                if (which == 0){
                    //camera tıklandı
                    // pd.setMessage("Updating Profile Picture");
                    //showImagePicDialog();
                    if (!checkCameraPermission()){
                        requestCameraPermission();
                    }
                    else{
                        pickFromCamera();
                    }
                }
                else if (which == 1){
                    //galeir tıklandı
                    //pd.setMessage("Updating Cover Picture");
                    if(!checkStoragePermission()){
                        requestStoragePermission();
                    }
                    else {
                        pickFromGallery();
                    }
                }
            }
        });
        //dialog oluşturme ve gösterme
        builder.create().show();

    }


    private void uploadProfileCoverPhoto(final Uri uri) {
        //Show progress dialog
        pd.show();

        //iki ayrı fonksiyon yerine profil resmi ve kapak resmi aynı fonksiyonda

        //firabase storage'da depolanan resmin yolu ve adı
        String filePathAndName = storagePath+ ""+ profileORCoverPhoto + "_"+ user.getUid();

        StorageReference storageReference2nd = storageReference.child(filePathAndName);
        storageReference2nd.putFile(uri)
                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        //resim depoya yüklendi, şimdi url'sini al ve kullanıcı veritabanında sakla
                        Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
                        while (!uriTask.isSuccessful());
                        Uri downloadUri = uriTask.getResult();

                        //resmin yüklenip yüklenmediğini ve url'nin alındığını kontrol edin
                        if (uriTask.isSuccessful()){
                            //resim yüklendi
                            //kullanıcı veritabanına url'i ekle/güncelle
                            HashMap<String, Object> results = new HashMap<>();

                            //ilk parametre profileOrCoverPhote image veya cover değerlerine sahip
                            //ikinci parametre firebase storage'da depolanan resmin url
                            results.put(profileORCoverPhoto, downloadUri.toString());

                            databaseReference.child(user.getUid()).updateChildren(results)
                                    .addOnSuccessListener(new OnSuccessListener<Void>() {
                                        @Override
                                        public void onSuccess(Void aVoid) {
                                            pd.dismiss();
                                            Toast.makeText(getActivity(), "Image Updated...", Toast.LENGTH_SHORT).show();
                                        }
                                    }).addOnFailureListener(new OnFailureListener() {
                                @Override
                                public void onFailure(@NonNull Exception e) {
                                    pd.dismiss();
                                    Toast.makeText(getActivity(), "Error Updating Image...", Toast.LENGTH_SHORT).show();

                                }
                            });

                        }
                        else {
                            //error
                            pd.dismiss();
                            Toast.makeText(getActivity(), "Some error occured", Toast.LENGTH_SHORT).show();
                        }


                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                         //bazı errorlar var, errorları al ve error mesajı göster, dissmis dialog
                        pd.dismiss();
                        Toast.makeText(getActivity(), e.getMessage(),Toast.LENGTH_SHORT).show();

                 }
        });

    }

    private void pickFromCamera() {
        //cihaz kamerasından görüntü alma
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, "Temp Pic");
        values.put(MediaStore.Images.Media.DESCRIPTION, "Temp Description");

        //resim uri'si
        image_uri = getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

        //camera başlatılması
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
        startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);


    }

    private void pickFromGallery() {
        //galeriden resim seçme
        Intent galleryIntent = new Intent(Intent.ACTION_PICK);
        galleryIntent.setType("image/*");
        startActivityForResult(galleryIntent, IMAGE_PICK_GALLERY_CODE);

    }


}

我的 AndroidManifes.xml 是

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gamze.pawsbook">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="29" />

    <uses-permission android:name="android.permission.CAMERA"
        android:maxSdkVersion="29" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".LoginActivity"></activity>
        <activity android:name=".DashboardActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".RegisterActivity" />
        <activity android:name=".MainActivity"></activity>
    </application>

</manifest>

我的 build.gradle(module:app)

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

android {
    compileSdkVersion 29

    defaultConfig {
        applicationId "com.gamze.pawsbook"
        minSdkVersion 22
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.material:material:1.1.0'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    // add the Firebase SDK for Google Analytics
    implementation 'com.google.firebase:firebase-analytics:17.2.2'

    //Firebase authentication library
    implementation 'com.google.firebase:firebase-auth:19.3.2'
    implementation 'com.google.android.gms:play-services-auth:18.1.0'

    //google sign in library
    implementation 'com.google.android.gms:play-services-auth:18.1.0'

    //Firebase Realtime Database
    implementation 'com.google.firebase:firebase-database:19.3.1'

    //Firebase Storage
    implementation 'com.google.firebase:firebase-storage:19.1.1'


    //Picasso library (resimleri eklemek için)
    implementation 'com.squareup.picasso:picasso:2.71828'


}

标签: javaandroidfirebasestorage

解决方案


ByteArrayOutputStream我建议在将 Bitmap 转换为not后尝试保存它URI

您可以按如下方式获取用户选择的位图 -

....
Bitmap newImage;                 //make it a global variable
.....

    @Override
        public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode != RESULT_CANCELED) {
                switch (requestCode) {
                    case 0:                            //Image from Camera
                        if (resultCode == RESULT_OK && data != null) {
                            newImage = (Bitmap) data.getExtras().get("data");
                            userImage.setImageBitmap(newImage);
                            newImageSet = true;
                        }
    
                        break;
                    case 1:                           //Image from gallery/user device
                        if (resultCode == RESULT_OK && data != null) {
                            Uri selectedImage = data.getData();
                            String[] filePathColumn = {MediaStore.Images.Media.DATA};
                            if (selectedImage != null) {
                                Cursor cursor = getActivity().getContentResolver().query(selectedImage,
                                        filePathColumn, null, null, null);
                                if (cursor != null) {
                                    cursor.moveToFirst();
                                    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                                    String picturePath = cursor.getString(columnIndex);
                                    newImage = BitmapFactory.decodeFile(picturePath);
                                    userImage.setImageBitmap(newImage);
                                    cursor.close();
                                }
                            }
                        }
                        break;
                }
            }
        }

获得新图像 bitmp 后,您可以将 Bitmap 放入 Firstore。

public void saveImageToFirbase(){

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            newImage.compress(Bitmap.CompressFormat.JPEG, 40, byteArrayOutputStream);
            StorageReference imgReference = FirebaseStorage.getInstance().getReference()
                    .child("User Profile Image")   
                    .child(FirebaseAuth.getInstance().getCurrentUser().getUid() + ".jpeg");
                    //adjust imgReference according to your database structure 

            imgReference.putBytes(byteArrayOutputStream.toByteArray())
                    .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            getDownloadUrl(imgReference);
                            
                        }
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Log.e(TAG, "onFailure: ", e.getCause());
                        }
                    });
}

这里Bitmap.CompressFormat.JPEG, 40整数值将是压缩级别。

方法 getgetDownloadUrl() -

private void getDownloadUrl(StorageReference storageReference) {
    storageReference.getDownloadUrl()
            .addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                    setUserProfileUrl(uri);
                }
            });
} 

至少您可以更新用户的个人资料并设置 ImageUrl -

private void setUserProfileUrl(Uri userProfileUrl) {
    FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();

    UserProfileChangeRequest userProfileChangeRequest = new UserProfileChangeRequest.Builder()
            .setPhotoUri(userProfileUrl).build();
    firebaseUser.updateProfile(userProfileChangeRequest)
            .addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    //some more update in your view
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.e(TAG, "onFailure: ", e.getCause());
                }
            });
}

快乐编码!


推荐阅读