如何使用Firebase存储中存储的图像?

时间:2019-03-28 20:52:51

标签: android firebase google-cloud-functions firebase-storage android-glide

我正在构建一个应用程序,该应用程序允许用户上传自己的图像以在该应用程序中使用。我正在使用Firebase Cloudstore数据库存储每个图像上的信息,并使用Firebase Storage存储实际图像。

因此,图像存储在Firebase存储中的名为images的文件夹中;其中,为它们指定了一个随机生成的名称,该名称存储在数据库的相应记录中。假设特定图像的名称为“ abcd.png”,那么数据库记录将如下所示:

symbols 
  > key1 > name: "Test symbol"
           uid: "User's randomly generated ID"
           description: "A description, as set by the user"
           url: "images/abcd.png"

现在,我想将所有用户上传的图像显示为小缩略图。我正在连接到数据库,查找属于当前用户的所有符号,然后使用ArrayAdapter来显示它们。不幸的是,我目前正在得到一排空白框。我不确定自己在做什么错。

符号显示在一个名为CurrentSymbolsFragment的片段中。布局(fragment_current_symbols.xml)为:

<android.support.constraint.ConstraintLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <GridView
        android:id="@+id/gridview_symbolList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:stretchMode="columnWidth"
    </GridView>

</android.support.constraint.ConstraintLayout>

,该类文件为:

public class FragmentCurrentSymbols extends Fragment {

    private ArrayList<ChartSymbol>           mSymbols;
    private Context             mContext;
    private GridView            mGridCurrentSymbols;

    static public FragmentCurrentSymbols newInstance(Context context,
                                                     ArrayList<ChartSymbol> symbols) {

        if(context == null)         return null;
        if(symbols == null)         return null;
        if(symbols.size() == 0)     return null;

        FragmentCurrentSymbols f = new FragmentCurrentSymbols();
        f.setRequiredData(context, symbols);

        return f;
    }

    public void setRequiredData(Context context, ArrayList<ChartSymbol> symbols) {

        if(context == null)         return;
        if(symbols == null)         return;
        if(symbols.size() == 0)     return;

        this.mContext = context;
        this.mSymbols = symbols;

    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        // Inflate layout
        View rootView = inflater.inflate(R.layout.fragment_current_symbols, container, false);

        mGridCurrentSymbols = rootView.findViewById(R.id.gridview_symbolList)

        initialiseWithSymbols();

        return rootView;
    }

    // Set symbols to be shown and initialise the view
    public void setSymbols(ArrayList<ChartSymbol> symbols) {
        mSymbols = symbols;
        initialiseWithSymbols();
    }

    /**
     * initialiseWithSymbols
     * Initialise the symbol list from the symbols
     * This takes the symbols and shows them, in order, in the grid
     **/
    public void initialiseWithSymbols() {

        if (mSymbols == null) return;

        // Now set up ChartSymbolAdapter to display symbols in grid
        ChartSymbolAdapter mSymbolAdapter = new ChartSymbolAdapter(mContext,
                R.layout.adapter_symbol_manage_layout,
                mSymbols);
        mGridCurrentSymbols.setAdapter(mSymbolAdapter);
        mGridCurrentSymbols.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    }

ChartSymbolAdapter类是:

public class ChartSymbolAdapter extends ArrayAdapter<ChartSymbol> {

    private Context                 mContext;
    private ArrayList<ChartSymbol>  mSymbolArray;
    private int                     layoutId;
    private ChartSymbol             selectedSymbol;

    public ChartSymbolAdapter(Context context, int layout_id, ArrayList<ChartSymbol> symbolArray) {
        super(context, layout_id, symbolArray);

        this.mContext=context;
        this.mSymbolArray=symbolArray;
        this.layoutId = layout_id;

    }

    private static class ViewHolder {
        private SymbolCell symbolCell;
        private TextView   symbolName, symbolKey;
    }

    @NonNull
    @Override
    public View getView(final int position, View convertView, @NonNull ViewGroup parent) {

        ViewHolder mViewHolder;
        StorageReference mStorageRef = FirebaseStorage.getInstance().getReference();

        if(convertView == null) {
            mViewHolder = new ViewHolder();
            LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            assert layoutInflater != null;
            convertView = layoutInflater.inflate(layoutId, parent, false);
            mViewHolder.symbolCell = convertView.findViewById(R.id.symbol_cell);
            mViewHolder.symbolName = convertView.findViewById(R.id.symbol_name);
            mViewHolder.symbolKey = convertView.findViewById(R.id.symbol_key);
            convertView.setTag(mViewHolder);
            // Now add the symbol
            ChartSymbol cellSymbol = mSymbolArray.get(position);
            // Find the url
            String drawableUrl = cellSymbol.getUrl();
            // If there's a Url, use it
            if(drawableUrl != null) {
                    Glide.with(getContext())
                            .load(drawableUrl)
                            .into(mViewHolder.symbolCell);
            }
        }

        return convertView;
    }

}

SymbolCell类扩展了ImageView

public class SymbolCell extends android.support.v7.widget.AppCompatImageView {

    ChartSymbol symbol;
    Paint paint;

    public SymbolCell(Context thisContext, AttributeSet attrs) {
        super(thisContext, attrs);

        paint = new Paint();

    }

    /**
     * onDraw
     * Draw a square to contain the given symbol.
     * @param canvas Canvas to draw on
     */
    protected void onDraw(Canvas canvas) {
        // Draw a box around cell
        // Set paint
        int stroke_width = 2;
        paint.setStrokeWidth(stroke_width);

        float height = getHeight();
        float width = getWidth();

        // Draw a black border for item
        paint.setColor(0xff000000);

        paint.setStyle(Paint.Style.STROKE);
        canvas.drawRect(0, 0, width - 2*stroke_width, height - 2*stroke_width, paint);

    }

}

尝试时,我会看到一系列空白框。存储符号的框数与我的数量一样多,这是正确的,但它们没有显示实际的图像。我已确保使用的图像的颜色恰好位于边缘,所以这不是问题。

这是我第一次在项目中使用Glide,所以我在那做错了吗?

使用调试器,可以看到从Firestore正确检索了符号,并且URL正确。我不确定如何检查Glide是否确实连接到存储来查找图像,但是肯定没有显示它。

谁能看到我要去哪里错了?

1 个答案:

答案 0 :(得分:0)

Cloud Storage中的每个图像都有一个gs(Google存储)URL,并且当然不能公开访问,这意味着您必须首先获得下载链接。

使用Firebase Storage SDK进行此操作。

  1. Do the normal setup
  2. Get a storage app
  3. Get a reference to your file in Firebase Storage
  4. Get direct download link