개인프로젝트

소켓통신으로 받은 데이터 Firebase Database에 저장 후 안드로이드에서 실시간 읽기

섭섭입니다 2020. 9. 3. 15:18

우선 저번에 했던 메모장으로 데이터를 주고받은 코드에 firebase에 데이터를 직접 입력할 수 있는 코드를 삽입하여 통신하여 받은 메모장 데이터를 바로 firebase realtime database 에 직접적으로 입력 해 주고 그것을 실시간으로 받아 올 것이다.

 

 

앱에서 사용할 것이니 안드로이드 스튜디오에서 프로젝트를 하나 생성 후 일단 firebase에 접속하여 자신의 앱을 등록한다.

 

 

console.firebase.google.com/

 

로그인 - Google 계정

하나의 계정으로 모든 Google 서비스를 Google 계정으로 로그인

accounts.google.com

firebase 콘솔 사이트에 로그인 하여서 자신의 프로잭트를 하나 만들면 된다.

 

 

 

프로젝트 만드는 것은 지난번에 했으니 그걸 참고하면 좋을 듯 하다.

 

프로젝트를 만들고 앱에서 사용할 경우에 다음과 같이 SDK를 추가해 주어야 한다고 하는데 동일하게 추가해 준다.

 

아래에 나와 있는 최신버전의 것들로 추가하면 좋을듯하다. 이것 때문인지는 모르겠으나 되지 않았던 적이 있었다

 

웬만하면 핸드폰 직접 연결 후 사용 권장

 

 

 

'

 

 

그 다음 자신의 안드로이드 스튜디오로 돌아가서 Firebase 설정을 해주면 되는 것 같다.

 

Tool -> Firebase -> Realtime Database -> save and retrieve data -> connect 어쩌구 클릭.

 

 

 

 

connect your app to Firebasa 에 연결하는 버튼이 있을 텐데 그걸 클릭하면 된다. 클릭하면 무슨 창이 뜰텐데 잘 마치는 것을 클릭하면 된다.

 

 

이렇게 하면 내 App이 firebase에 등록되어 사용할 수 있을 것이다. 

 

 

 

 

이때, 에물레이터만 켜서 사용하면 연결이 안 되는 경우가 있었다... 가급적 안드로이드 핸드폰을 직접 꽂아 사용해야 할듯 하다


이제는 python으로 소켓통신한 데이터를 메모장으로 받아서 적어넣을 것인데

 

메모장에서 받은 것을 firebase 로 적어넣는 것을 할 것이다.

 

 

 

아래의 간단히 database를 수정하는? 입력하는 코드를 이용하여 저번에 사용하였던 코드를 조금 수정하였다.

 

하지만 아래의 코드에는 패키지를 install 하는 명령어가 있었다. VisualStudio 에서 C만 해보던 나는 여기서 install을?

 

어려웠다. VisualStudio를 사용하였기 때문에 그곳에서 python을 사용하는 것이 익숙치 않았다. 따라서 패키지를 install

 

하는 것 조차 어려웠다.  (패키지를 install 하는 방법은 아래에 있다.)

 

 

 

 

 

 < visualstudio에서 python 패키지를 install 하는 방법은 다음과 같다. >

 

 

도구 -> python -> python 환경 클릭하면 오른쪽 환경창이 뜰텐데 여기서 자신이 다운받을 환경을 클릭 후 

 

화면에 패키지라고 되어있는 부분이원래 "개요" 라고 되어있는 부분이다. 개요 -> 패키지(PyPl) 선택 한 다음

 

밑에 검색창에 자신이 install 할 패키지를 적은 뒤 명령 실행을 누르면 된다.

 

 

 

 

아래는 firebase에 data를 update하는 간단한 예제 코드이다.

< firebase_Update >

#-*-coding:utf-8 -*-
'''
pip install firebase_admin
'''
import firebase_admin
from firebase_admin import credentials, db



#Firebase 콘솔에서 비밀키를 생성하고 파일 다운로드 -> key json 파일로 인증
cred = credentials.Certificate('비밀키 생성하여 json파일 이름 복붙.json')
firebase_admin.initialize_app(cred, {
	'databaseURL' : '자신의 firebase database url 입력.'
})

# 값 업데이트 
ref = db.reference()
ref.update({'금일 출입 인원 수' : '71'})

 

 

1. 우선 비공개 키 name를 넣어주어야 한다.

 

cred = credentials.Certificate(' ') 여기서 괄호 안 ' ' 에다가 firebase database를 만든 뒤에 [ 새 비공개 키 생성 ] 버튼을 클릭하여 그 파일의 이름을 확장자 명 까지 복붙하는 것이 중요하다.

 

 

비밀 키 생성 버튼은 다음과 같다. 

 

 

[새 비공개 키 생성] 버튼을 클릭하게 되면 json 파일이 다운로드 되는데 그것의 파일명을 붙여넣기 하면 된다.

 

 

 

2. 데이터 입력

 

여기서 ref.updata( { '데이터 명? ' : ' 실제 데이터 값 '} )  왼쪽 인자에는 데이터명이 들어가고, 오른쪽 인자에는 실제 데이터 값이 들어간다. 이렇게 해서 넣게되면 다음과 같이 들어간다.

 

 

 


 

 

이렇게 되는 것을 이용해서 받은 데이터를 바로 넣을 것이다.

 

< Server >

import socket


HOST = '127.0.0.1'

PORT = 9999        

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)


# bind 함수는 소켓을 특정 네트워크 인터페이스와 포트 번호에 연결하는데 사용됩니다.
# HOST는 hostname, ip address, 빈 문자열 ""이 될 수 있습니다.
# 빈 문자열이면 모든 네트워크 인터페이스로부터의 접속을 허용합니다. 
# PORT는 1-65535 사이의 숫자를 사용할 수 있습니다.  
server_socket.bind((HOST, PORT))

# 서버가 클라이언트의 접속을 허용하도록 합니다. 
server_socket.listen()

# accept 함수에서 대기하다가 클라이언트가 접속하면 새로운 소켓을 리턴합니다. 
client_socket, addr = server_socket.accept()

# 접속한 클라이언트의 주소입니다.
print('Connected by', addr)

copy ='0'
    
# 무한루프를 돌면서 
while True:
     
    hellofile = 'C:/Users/junseop/source/repos/MomoSoket_python_server/MomoSoket_python_server/hello.txt'

    f = open(hellofile, 'r', encoding="utf-8" )
    s = f.read()
    f.close()
   
    if copy == s:
        continue
    else:
        print('메모장의 내용',s)
         # 메모장의 내용을 클라이언트로 전송    
        copy = s
        client_socket.sendall(s.encode())


    
# 소켓을 닫습니다.
client_socket.close()
server_socket.close()

 

서버코드는 별 다른 게 없다. 다른 컴퓨터 이기에 그곳의 정보를 넘겨 줄 것이다.

 

 

< Client >

#-*-coding:utf-8 -*-
'''
pip install firebase_admin
'''
import firebase_admin
from firebase_admin import credentials, db

import socket

HOST = '127.0.0.1'  
PORT = 9999   

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client_socket.connect((HOST, PORT))

copy ='0'

    #Firebase 콘솔에서 비밀키를 생성하고 파일 다운로드 -> key json 파일로 인증
cred = credentials.Certificate('비공개 키 name . json')  # 이부분 수정
firebase_admin.initialize_app(cred, {
             'databaseURL' : 'firebase databse url'  # 이부분 수정
    })


while True:

    data = client_socket.recv(1024)

    if copy == data:
            continue
    else:
            print('서버로 부터 받은 메모장의 내용', repr(data.decode()))
        
            copy = data

            textfile = 'C:/Users/junseop/source/repos/MemoSoket_Python/MemoSoket_Python/client.txt'

            f = open(textfile, 'w',encoding="utf-8" )
            f.write(data.decode())


            f = open(textfile, 'r', encoding="utf-8" )
            s = f.read()
            f.close()



            # 값 업데이트 
            ref = db.reference()
            ref.update({'금일 출입 인원 수' : s })

# 소켓을 닫습니다.
client_socket.close()

 

똑같이 while문에 쓰기로 열어서 받은 걸 쓰고, 읽기로 열어서 그것을 s에 저장하여 firebase에 업데이트 한다.

 

 

python 코드가 작성되었다.

 

 


 

이제는  안드로이드 스튜디오에서 TextView를 활용해 그것을 읽어 올 것이다.

 

우선 제일 위에서 firebase 연결을 해 주었으면 SDK도 설치가 완료 되었다.

 

 

< MainActivity.java >

package com.example.firebase_db_exam;
import android.os.Bundle;

import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    FirebaseDatabase database;
    DatabaseReference myRef;

    TextView tvMessage;
    EditText etNewMessage;
    Button btUpdate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvMessage = (TextView) findViewById(R.id.textview);
        etNewMessage = (EditText) findViewById(R.id.edittext);
        btUpdate = (Button) findViewById(R.id.button);

        database = FirebaseDatabase.getInstance();
        myRef = database.getReference("금일 출입 인원 수");

        //버튼 이벤트
        btUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String newMessage = etNewMessage.getText().toString();
                myRef.setValue(newMessage);
            }
        });

        // Read from the database
        // 그리고 데이터베이스에 변경사항이 있으면 실행된다.
        myRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                // This method is called once with the initial value and again
                // whenever data at this location is updated.
                String value = dataSnapshot.getValue(String.class);
                //데이터를 화면에 출력해 준다.
                tvMessage.setText(value);
                Log.d(TAG, "Value is: " + value);
            }

            @Override
            public void onCancelled(DatabaseError error) {
                // Failed to read value
                Log.w(TAG, "Failed to read value.", error.toException());
            }
        });
    }
}


 

 

myRef = database.getReference("금일 출입 인원 수");   

 

요 부분이 데이터의 데이터의 이름을 쓰는 부분인데 그 곳에서 데이터를 가져오는 부분이다.

 

 

 

 

 

 

 

마무리

 

1. 서버에서 서버 자신의 메모장의 내용을 읽어 데이터를 보내줌

 

2. 클라이언트에서 클라이언트 자신의 메모장에 서버가 보내준 데이터를 씀

 

3. 클라이언트에서 자신의 메모장에 씀과 동시에 그 데이터를 firebase database에 저장함

 

4. 안드로이드에서는 firebase realtime database 를 이용하여 실시간으로 데이터를 받아 Textview에 출력 함

 

 

 

 

해맷던 점

 

1. firebase database 사용할 때 안드로이드 스튜디오 에뮬레이터 사용하면 안 된 적이 있음.. 많은 시간 고생

 

2. fileInputStream 이나 다른 방법을 이용하여 했을 때는 실시간으로 불러오는 것이 제한되었음.

 

3. 안드로이드 스튜디오에서 최신 버전의 SDK를 설치하여야 되는 것 같은 느낌 이었다.

 

4. 비주얼스튜디오로 python 코드 짤 때 패키치 설치가 애먹었다.  그리고 key name 적는 걸 몰라서 해맷다.

 

 

 

 

 

 

 

 

 

 

참고 블로그 : blog.naver.com/PostView.nhnblogId=cosmosjs&logNo=220968036346&beginTime=0&jumpingVid=&from=search&redirect=Log&widgetTypeCall=true