Firebase中dataImage数据误传至dataStock节点的问题求助
问题排查:Firebase数据上传字段错位
我在Firebase中新增了名为datastock的子节点,Android端对应视图也设置了唯一ID,期望数据能准确上传到各自对应的子节点。但原本应传入dataImage的数据错误传入了dataStock节点,Firebase数据截图如下:
我已多次检查视图ID是否混淆,但未发现问题,请帮我排查遗漏点,相关代码如下:
activity_upload.xml
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".UploadActivity"> <androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:layout_marginEnd="20dp" android:layout_marginStart="20dp" app:cardCornerRadius="30dp" app:cardElevation="20dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_gravity="center_horizontal" android:padding="20dp" android:background="@drawable/lavender_border"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Upload Data" android:textSize="30sp" android:textAlignment="center" android:textColor="@color/lavender"/> <ImageView android:layout_width="match_parent" android:layout_height="200dp" android:src="@drawable/uploadimg" android:id="@+id/uploadImage" android:layout_marginTop="10dp" android:scaleType="fitXY"/> <EditText android:layout_width="300dp" android:layout_height="60dp" android:id="@+id/uploadTopic" android:background="@drawable/lavender_border" android:layout_marginTop="20dp" android:padding="16dp" android:hint="Enter product name" android:inputType="text" android:gravity="start|center_vertical" android:layout_gravity="center" android:textColor="@color/lavender"/> <EditText android:layout_width="300dp" android:layout_height="80dp" android:id="@+id/uploadDesc" android:background="@drawable/lavender_border" android:layout_marginTop="20dp" android:padding="16dp" android:hint="Enter description" android:gravity="start|center_vertical" android:inputType="textMultiLine" android:layout_gravity="center" android:textColor="@color/lavender"/> <EditText android:layout_width="300dp" android:layout_height="60dp" android:id="@+id/uploadLang" android:background="@drawable/lavender_border" android:layout_marginTop="20dp" android:padding="16dp" android:hint="Enter price" android:inputType="number" android:gravity="start|center_vertical" android:layout_gravity="center" android:textColor="@color/lavender"/> <EditText android:layout_width="300dp" android:layout_height="60dp" android:id="@+id/uploadStock" android:background="@drawable/lavender_border" android:layout_marginTop="20dp" android:padding="16dp" android:hint="Enter stock" android:inputType="number" android:gravity="start|center_vertical" android:layout_gravity="center" android:textColor="@color/lavender"/> <Button android:layout_width="300dp" android:layout_height="60dp" android:text="Save" android:id="@+id/saveButton" android:textSize="18sp" android:layout_marginTop="20dp" android:layout_gravity="center" app:cornerRadius = "20dp"/> </LinearLayout> </androidx.cardview.widget.CardView> </ScrollView>
UploadActivity.java
package com.example.admin_app; import androidx.activity.result.ActivityResult; import androidx.activity.result.ActivityResultCallback; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import android.app.Activity; import android.app.AlertDialog; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.Task; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.storage.FirebaseStorage; import com.google.firebase.storage.StorageReference; import com.google.firebase.storage.UploadTask; import java.text.DateFormat; import java.util.Calendar; import java.util.Currency; public class UploadActivity extends AppCompatActivity { ImageView uploadImage; Button saveButton; EditText uploadTopic, uploadDesc, uploadLang, uploadStock; String imageURL; Uri uri; //CurrencyEditText uploadLang; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_upload); uploadImage = findViewById(R.id.uploadImage); uploadDesc = findViewById(R.id.uploadDesc); uploadTopic = findViewById(R.id.uploadTopic); uploadLang = findViewById(R.id.uploadLang); uploadStock = findViewById(R.id.uploadStock); saveButton = findViewById(R.id.saveButton); ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { if (result.getResultCode() == Activity.RESULT_OK){ Intent data = result.getData(); assert data != null; uri = data.getData(); uploadImage.setImageURI(uri); } else { Toast.makeText(UploadActivity.this, "No Image Selected", Toast.LENGTH_SHORT).show(); } } } ); uploadImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent photoPicker = new Intent(Intent.ACTION_PICK); photoPicker.setType("image/*"); activityResultLauncher.launch(photoPicker); } }); saveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { saveData(); } }); } public void saveData(){ StorageReference storageReference = FirebaseStorage.getInstance().getReference().child("Android Images") .child(uri.getLastPathSegment()); AlertDialog.Builder builder = new AlertDialog.Builder(UploadActivity.this); builder.setCancelable(false); builder.setView(R.layout.progress_layout); AlertDialog dialog = builder.create(); dialog.show(); storageReference.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl(); while (!uriTask.isComplete()); Uri urlImage = uriTask.getResult(); imageURL = urlImage.toString(); uploadData(); dialog.dismiss(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { dialog.dismiss(); } }); } public void uploadData(){ String title = uploadTopic.getText().toString(); String desc = uploadDesc.getText().toString(); String lang = uploadLang.getText().toString(); String stock = uploadStock.getText().toString(); DataClass dataClass = new DataClass(title, desc, lang, stock, imageURL); //We are changing the child from title to currentDate, // because we will be updating title as well and it may affect child value. String currentDate = DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()); FirebaseDatabase.getInstance().getReference("Products").child(currentDate) .setValue(dataClass).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()){ Toast.makeText(UploadActivity.this, "Saved", Toast.LENGTH_SHORT).show(); finish(); } } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Toast.makeText(UploadActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); } }); } }
MyAdapter.java
package com.example.admin_app; import android.content.Context; import android.content.Intent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import java.util.ArrayList; import java.util.List; import androidx.annotation.NonNull; import androidx.cardview.widget.CardView; import androidx.recyclerview.widget.RecyclerView; public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> { private Context context; private List<DataClass> dataList; public MyAdapter(Context context, List<DataClass> dataList) { this.context = context; this.dataList = dataList; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false); return new MyViewHolder(view); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { Glide.with(context).load(dataList.get(position).getDataImage()).into(holder.recImage); holder.recTitle.setText(dataList.get(position).getDataTitle()); holder.recDesc.setText(dataList.get(position).getDataDesc()); holder.recLang.setText(dataList.get(position).getDataLang()); holder.recStock.setText(dataList.get(position).getDataStock()); holder.recCard.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(context, DetailActivity.class); intent.putExtra("Image", dataList.get(holder.getAdapterPosition()).getDataImage()); intent.putExtra("Description", dataList.get(holder.getAdapterPosition()).getDataDesc()); intent.putExtra("Name", dataList.get(holder.getAdapterPosition()).getDataTitle()); intent.putExtra("Key",dataList.get(holder.getAdapterPosition()).getKey()); intent.putExtra("Price", dataList.get(holder.getAdapterPosition()).getDataLang()); intent.putExtra("Stock", dataList.get(holder.getAdapterPosition()).getDataStock()); context.startActivity(intent); } }); } @Override public int getItemCount() { return dataList.size(); } public void searchDataList(ArrayList<DataClass> searchList){ dataList = searchList; notifyDataSetChanged(); } } class MyViewHolder extends RecyclerView.ViewHolder{ ImageView recImage; TextView recTitle, recDesc, recLang, recStock; CardView recCard; public MyViewHolder(@NonNull View itemView) { super(itemView); recImage = itemView.findViewById(R.id.recImage); recCard = itemView.findViewById(R.id.recCard); recDesc = itemView.findViewById(R.id.recDesc); recLang = itemView.findViewById(R.id.recPriority); recTitle = itemView.findViewById(R.id.recTitle); recStock = itemView.findViewById(R.id.recStock); } }
DataClass.java
package com.example.admin_app; public class DataClass { private String dataTitle; private String dataDesc; private String dataLang; private String dataImage; private String dataStock; private String key; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public String getDataTitle() { return dataTitle; } public String getDataDesc() { return dataDesc; } public String getDataLang() { return dataLang; } public String getDataStock() { return dataStock; } public String getDataImage() { return dataImage; } public DataClass(String dataTitle, String dataDesc, String dataLang, String dataImage, String dataStock) { this.dataTitle = dataTitle; this.dataDesc = dataDesc; this.dataLang = dataLang; this.dataImage = dataImage; this.dataStock = dataStock; } public DataClass(){ } }
问题根源与修复方案
问题根源
数据错位的核心原因是DataClass构造函数的参数顺序和UploadActivity中创建实例时传入的参数顺序不匹配:
- DataClass构造函数定义的参数顺序:
dataTitle→dataDesc→dataLang→dataImage→dataStock - UploadActivity中创建实例时传入的顺序:
title→desc→lang→stock→imageURL
这就导致图片URL(imageURL)被错误传入dataStock字段,库存值(stock)被传入dataImage字段,最终出现Firebase数据错位。
修复方案
修改UploadActivity中uploadData()方法里创建DataClass实例的参数顺序,和构造函数定义一致:
// 原错误代码 // DataClass dataClass = new DataClass(title, desc, lang, stock, imageURL); // 修改后的正确代码 DataClass dataClass = new DataClass(title, desc, lang, imageURL, stock);
修改后,图片URL会正确传入dataImage节点,库存值传入datastock节点,数据错位问题即可解决。
内容的提问来源于stack exchange,提问作者Byakuran
相关产品推荐
相关产品推荐

