1000sj
SJ CODE
1000sj
전체 방문자
오늘
어제
  • 분류 전체보기
    • 알고리즘
    • 네트워크 보안
      • 네트워크
      • 보안
      • CTF
      • Exploit
    • System Programming
      • Operating System
      • Compiler
      • Device Driver
      • Emulator
    • Application Programming
      • Script
      • Android
    • 클라우드 컴퓨팅
      • Cloud Native
      • Public Cloud
      • Infrastructure
      • Database
      • DevOps
    • 트러블슈팅
    • ETC
      • 문화 생활
      • 커뮤니티

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
1000sj

SJ CODE

[Android/Firebase] Firebase Database, Storage
Application Programming/Android

[Android/Firebase] Firebase Database, Storage

2021. 6. 30. 01:04

Demo

 

0. Firebase 와 Android studio 연동

 

1. Database 생성

firebase console 에서 create database 를 test 버전으로 Create 해준다.

storage, database rules를 체크한다. 여기서 read, write 제약을 걸 수 있다.

 

 

2. Dependencty 추가

android studio tools >> firebase >> database, storage 를 add하면 자동으로 추가된다.

implementation 'com.google.firebase:firebase-database:20.0.0'
implementation 'com.google.firebase:firebase-storage:20.0.0'

 

 

3. 데이터베이스에 쓰기, 메모리 데이터에서 업로드

  • Database에 쓰기
databaseReference.setValue(data); // data는 따로 Dao 객체만드는게 좋을듯

 

  • 업로드하기
    • byte
    • stream
    • file

byte[]는 파일의 전체 콘텐츠를 메모리에 한 번에 담아서 보내주기때문에 메모리를 절약하려면 putStream()이나 putFile()을 사용하는게 좋다고 한다.

ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 바이트 배열을 쓸 수 있는 스트림을 준비
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos); // 50%로 압축하여 jpeg 형식으로 스트림에 비트맵을 저장
byte[] finalimg = baos.toByteArray(); // 스트림을 바이트 배열로 변환
final StorageReference filePath; // 내부적으로 storage reference를 생성 << 파일의 전체 경로를 가리키는 참조
filePath = storageReference.child("Notice").child(finalimg + "jpg"); // notice/finalimg + "jpg"로 저장
final UploadTask uploadTask = filePath.putBytes(finalimg);

 

UploadNotice.java

package com.sjcoding.admincollegeapp;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.cardview.widget.CardView;

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.DatabaseReference;
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.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class UploadNotice extends AppCompatActivity {
    private CardView addImage; // 이미지 업로드 버튼
    private ImageView noticeImageView; // 가져온 사진 그릴 공간
    private EditText noticeTitle;
    private Button uploadNoticeButton; // notice 업로드 버튼

    private final int REQ = 1000; // 응답
    private ProgressDialog pd; // 다이알로그

    private DatabaseReference databaseReference;
    private StorageReference storageReference;

    private String downloadUrl = "";
    private Bitmap bitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_upload_notice);
        // 레퍼런스를 가져옴
        databaseReference = FirebaseDatabase.getInstance().getReference();
        storageReference = FirebaseStorage.getInstance().getReference();

        pd = new ProgressDialog(this);

        noticeImageView = (ImageView) findViewById(R.id.iv_notice);
        noticeTitle = findViewById(R.id.notice_title);
        // notice 업로드 버튼 클릭클릭!
        uploadNoticeButton = findViewById(R.id.btn_upload_notice);
        uploadNoticeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(noticeTitle.getText().toString().isEmpty()) {
                    noticeTitle.setError("제목은 필수사항입니다.");
                    noticeTitle.requestFocus();
                }else if(bitmap == null) {
                    uploadData();
                }else {
                    uploadImage();
                }
            }
        });
        // image 업로드 버튼 클릭클릭!
        addImage = findViewById(R.id.add_image);
        addImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openGallery();
            }
        });
    }

    // gallery 열기
    private void openGallery() {
        Intent pickImage = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(pickImage, REQ);
    }

    // 결과값 bitmap 변환해서 그려줌
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == REQ && resultCode == Activity.RESULT_OK) {
            Uri uri = data.getData();
            try {
                bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
            } catch (IOException e) {
                e.printStackTrace();
            }
            noticeImageView.setImageBitmap(bitmap);
        }
    }

    // 이미지파일 업로드
    private void uploadImage() {
        pd.setMessage("Uploading...");
        pd.show();

        ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 바이트 배열을 쓸 수 있는 스트림을 준비
        bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos); // 50%로 압축하여 jpeg 형식으로 스트림에 비트맵을 저장
        byte[] finalimg = baos.toByteArray(); // 스트림을 바이트 배열로 변환
        final StorageReference filePath; // 내부적으로 storage reference를 생성 << 파일의 전체 경로를 가리키는 참조
        filePath = storageReference.child("Notice").child(finalimg + "jpg"); // notice/finalimg + "jpg"로 저장
        final UploadTask uploadTask = filePath.putBytes(finalimg);
        uploadTask.addOnCompleteListener(UploadNotice.this, new OnCompleteListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
                if(task.isSuccessful()) {
                    uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {

                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            filePath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                                @Override
                                public void onSuccess(Uri uri) {
                                    downloadUrl = String.valueOf(uri);
                                    uploadData(); // 최종 데이터 업로드
                                }
                            });
                        }
                    });
                } else {
                    pd.dismiss();
                    Toast.makeText(UploadNotice.this, "Notice uploaded", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    // 최종 데이터 업로드
    private void uploadData() {
        // Notice 디렉토리 아래에 생성
        databaseReference = databaseReference.child("Notice");
        // 필드값 key
        final String uniqueKey = databaseReference.push().getKey();
        // 필드값 title
        String title = noticeTitle.getText().toString();
        // 필드값 date
        Calendar calForDate = Calendar.getInstance();
        SimpleDateFormat currentDate = new SimpleDateFormat("dd-MM-yy");
        String date = currentDate.format(calForDate.getTime());
        // 필드값 time
        Calendar calForTime = Calendar.getInstance();
        SimpleDateFormat currentTime = new SimpleDateFormat("hh:mm a");
        String time = currentDate.format(calForDate.getTime());

        NoticeData noticeData = new NoticeData(title, downloadUrl, date, time, uniqueKey);

        databaseReference.child(uniqueKey).setValue(noticeData).addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void unused) {
                pd.dismiss();
                Toast.makeText(UploadNotice.this, "Notice uploaded", Toast.LENGTH_SHORT).show();
            }
        }).addOnFailureListener(new OnFailureListener(){
            @Override
            public void onFailure(@NonNull Exception e) {
                pd.dismiss();
                Toast.makeText(UploadNotice.this, "Something went wrong", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

 

activity_upload_notice.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"
    tools:context=".UploadNotice"
    android:padding="16dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.google.android.material.card.MaterialCardView
            android:layout_width="130dp"
            android:layout_height="150dp"
            android:layout_margin="10dp"
            android:id="@+id/add_image"
            app:cardElevation="5dp"
            android:layout_gravity="center">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:gravity="center">
                <ImageView
                    android:layout_width="64dp"
                    android:layout_height="64dp"
                    android:background='@drawable/circle_purple'
                    android:src="@drawable/ic_notice"
                    android:padding="15dp"/>
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="@color/lightGray"
                    android:layout_marginTop="10dp"/>
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Select Image"
                    android:textStyle="bold"
                    android:padding="5dp"
                    android:layout_marginTop="10dp"
                    android:textColor="@color/textColor"/>

            </LinearLayout>

        </com.google.android.material.card.MaterialCardView>

        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="16dp"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
            <com.google.android.material.textfield.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Notice title"
                android:id="@+id/notice_title"/>
        </com.google.android.material.textfield.TextInputLayout>
        <com.google.android.material.button.MaterialButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Upload Notice"
            android:layout_marginTop="16dp"
            android:textAllCaps="false"
            android:id="@+id/btn_upload_notice"/>
        <com.google.android.material.card.MaterialCardView
            android:layout_width="match_parent"
            android:layout_height="400dp">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:id="@+id/iv_notice"/>
        </com.google.android.material.card.MaterialCardView>


    </LinearLayout>
</ScrollView>

 

 

 

 

Ref

  • firebase database
  • firebase storage

 

'Application Programming > Android' 카테고리의 다른 글

[Android/Firebase] Firebase CRUD  (0) 2021.07.03
[Android/Firebase] Firebase Upload pdf  (0) 2021.07.01
[Android/Java] 갤러리 열고 그리기 MediaStore, bitmap  (0) 2021.06.29
[Android/Java] Fragment Bottom Navigation view  (0) 2021.06.28
[Android/Java] Fragment간 값 전달  (0) 2021.06.28
    'Application Programming/Android' 카테고리의 다른 글
    • [Android/Firebase] Firebase CRUD
    • [Android/Firebase] Firebase Upload pdf
    • [Android/Java] 갤러리 열고 그리기 MediaStore, bitmap
    • [Android/Java] Fragment Bottom Navigation view
    1000sj
    1000sj

    티스토리툴바