2026/04/14

오늘의 이야기

Python을 이용한 Firebase Realtime Database 생성  Android Studio를 통한 데이터 읽기


앱 개발자로 살아보기



안녕하세요! 오늘은 Python을 사용해 Excel 데이터를 Firebase Realtime Database에 업로드하고, Android Studio를 통해 해당 데이터를 읽어오는 방법을 소개하려고 합니다.  과정에서 발생할  있는 주요 오류와 대처 방안도 함께 살펴보겠습니다.


Python을 이용한 Firebase Realtime Database 생성


1. 라이브러리 설치


먼저 필요한 라이브러리를 설치합니다.



sh




pip install openpyxl firebase-admin




2. Firebase 초기화  Excel 파일 읽기


다음 코드를 작성하여 Excel 파일을 읽고 Firebase에 데이터를 업로드합니다.



python




import openpyxl
import firebase_admin
from firebase_admin import credentials, db

# Firebase 초기화
cred = credentials.Certificate("serviceAccountKey.json")
firebase_admin.initialize_app(cred, {
'databaseURL': 'https://your-database-name.firebaseio.com/'
})

# Excel 파일 읽기
workbook = openpyxl.load_workbook('your_excel_file.xlsx')
sheet = workbook.active

# 데이터 Firebase에 업로드
for row in sheet.iter_rows(min_row=2, values_only=True): # 첫 번째 행은 헤더로 간주
data = {
'column1': row[0],
'column2': row[1],
# 필요한 만큼 추가
}
db.reference('path/to/your/data').push(data)

print("데이터가 성공적으로 Firebase에 저장되었습니다.")




Android Studio에서 Firebase 데이터 읽기


1. Gradle 설정


build.gradle 파일에 Firebase 의존성을 추가합니다.



gradle




dependencies {
implementation 'com.google.firebase:firebase-database:20.0.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
}




2. ViewModel 정의  LiveData 설정


다음 코드를 작성하여 ViewModel에서 Firebase 데이터를 읽고 LiveData에 저장합니다.



kotlin




class MyViewModel : ViewModel() {
private val database = FirebaseDatabase.getInstance().reference

private val _data = MutableLiveData<List<Record>>()
val data: LiveData<List<Record>> get() = _data

init {
fetchDataFromFirebase()
}

private fun fetchDataFromFirebase() {
database.child("path/to/data").addChildEventListener(object : ChildEventListener {
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
val recordList = _data.value?.toMutableList() ?: mutableListOf()
val record = snapshot.getValue(Record::class.java)
record?.let { recordList.add(it) }
_data.value = recordList
}
override fun onCancelled(error: DatabaseError) {}
override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) {}
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {}
override fun onChildRemoved(snapshot: DataSnapshot) {}
})
}
}




3. Activity에서 LiveData 관찰


Activity에서 ViewModel과 LiveData를 관찰하여 UI를 업데이트합니다.



kotlin




class MainActivity : AppCompatActivity() {
private val myViewModel: MyViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

myViewModel.data.observe(this, Observer { recordList ->
// UI 업데이트
for (record in recordList) {
println("Field1: ${record.field1}")
println("Field2: ${record.field2}")
println("Field3: ${record.field3}")
println("Field4: ${record.field4}")
println("Field5: ${record.field5}")
println("Field6: ${record.field6}")
}
})
}
}




오류  대처 방안



  1. Firebase Realtime Database 연결 강제 종료

    • 오류: Firebase Database connection was forcefully killed by the server.

    • 원인: 데이터베이스가 다른 지역에 위치.

    • 해결: 데이터베이스 URL을 올바르게 설정.



  2. Firebase 데이터 클래스  생성자 오류

    • 오류: Class does not define a no-argument constructor.

    • 해결: 데이터 클래스에  생성자 추가.


    • kotlin




      data class Record(
      val field1: String? = null,
      val field2: String? = null,
      // 필요한 필드 추가
      ) {
      constructor() : this(null, null, null, null, null, null)
      }







이렇게 하면 Python과 Android Studio를 사용해 Firebase Realtime Database를 효과적으로 관리할  있습니다. 추가적인 질문이나 도움이 필요하시면 언제든지 말씀해 주세요!





오늘의 이야기

Room Database Migration: 칼럼 추가와 데이터 타입 변경


database migration



 


안녕하세요! 이번 포스트에서는 Room 데이터베이스에서 마이그레이션을 통해 칼럼을 추가하고 데이터 타입을 변경하는 방법에 대해 알아보겠습니다.  포스트를 통해 데이터베이스 마이그레이션을 원활하게 처리하는 방법을 배우실  있습니다.


1. 기본적인 칼럼 추가


새로운 칼럼을 추가할 때는 마이그레이션 클래스를 작성하여 ALTER TABLE SQL 명령어를 사용합니다. 예를 들어, new_column이라는 INTEGER 칼럼을 example_table에 추가하는 방법은 다음과 같습니다:



kotlin




import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase

val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE example_table ADD COLUMN new_column INTEGER NOT NULL DEFAULT 0")
}
}




2. Boolean 칼럼 추가


Room에서는 Boolean 타입을 직접 지원하지 않기 때문에, INTEGER 타입을 사용하여 0과 1로 표현합니다. deviceInfo 테이블에 deviceSelected라는 Boolean 칼럼을 추가하는 예제는 다음과 같습니다:



kotlin




val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE deviceInfo ADD COLUMN deviceSelected INTEGER NOT NULL DEFAULT 0")
}
}




3. 데이터베이스 빌더에 마이그레이션 추가


데이터베이스 빌더에 마이그레이션을 추가하여 데이터베이스 인스턴스를 생성합니다:



kotlin




val db = Room.databaseBuilder(applicationContext, AppDatabase::class.java, "database-name")
.addMigrations(MIGRATION_1_2)
.build()




4. 데이터베이스 버전 업데이트


@Database 어노테이션에서 데이터베이스 버전을 업데이트합니다:



kotlin




@Database(entities = [DeviceInfo::class], version = 2)
abstract class AppDatabase : RoomDatabase() {
abstract fun deviceInfoDao(): DeviceInfoDao
}




5. 전체 마이그레이션 과정 요약


 단계를 통해 데이터베이스 마이그레이션을 원활하게 처리할  있습니다. 새로운 칼럼을 추가하거나 데이터 타입을 변경할 때는 항상 주의 깊게 작업해야 하며, 마이그레이션 로직을 정확하게 작성하는 것이 중요합니다.








오늘의 이야기


#스하리1000명프로젝트

오늘 내가 만든앱 하나 알려주고 싶어, 이 앱은 알림수집기 라고 이름을 붙였는 데,
내 폰에 표시 되는 알림을 읽어서 내가 지정한 단어가 들어 있고, 지출기록을 남겨야 하는 알림이
있으면 수집하고, 카카오톡으로 친구에게 전달해 주는 기능을 구현해 줄꺼야. 📲

이번 패치에서는 하루 한번 지정한 시간에 나에게 알림(노티) 하도록 기능을 추가 했어. 🙏
한번 써보고 불편한 거 있으면 말해줘.

앱 바로가기
👉 https://play.google.com/store/apps/details?id=com.nari.notify2kakao





오늘의 이야기

Python 정규식으로 문자열에서 특정 문자만 남기기

python re.sub



Python에서 정규식을 사용하여 문자열에서 특정 문자만 남기고 나머지를 제거하는 방법을 알아보겠습니다. 예를 들어, 영문자, 숫자, 밑줄(_), 하이픈(-), <, 그리고 공백을 제외한 모든 문자를 제거하는 방법을 살펴보겠습니다.

정규식 치환 예제
다음은 정규식을 사용하여 문자열에서 특정 문자만 남기고 나머지를 제거하는 예제입니다:

Python

import re

text = "Hello, World! 1234 @#$%^&*()_+-<> "

# 정규식을 사용하여 영문자, 숫자, 밑줄, 하이픈, <, 공백을 제외한 모든 문자 치환
result = re.sub(r'[^A-Za-z0-9_<\-\s]', '', text)

print(result)  # "Hello World 1234 _-<> "

AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.
코드 설명
모듈 임포트: re 모듈을 임포트합니다.
문자열 정의: 예제로 사용할 문자열을 정의합니다.
정규식 패턴: [^A-Za-z0-9_<\-\s] 패턴을 사용하여 영문자, 숫자, 밑줄, 하이픈, <, 공백을 제외한 모든 문자를 빈 문자열로 치환합니다.
[^...]: 대괄호 안에 있는 문자들을 제외한 모든 문자를 매칭합니다.
A-Za-z: 모든 영문자.
0-9: 모든 숫자.
_: 밑줄.
-: 하이픈.
<: < 문자.
\s: 공백 문자.
치환 및 출력: re.sub() 함수를 사용하여 치환하고 결과를 출력합니다.
결론
이 방법을 사용하면 문자열에서 특정 문자만 남기고 나머지를 제거할 수 있습니다. 정규식을 활용하면 다양한 문자열 처리 작업을 효율적으로 수행할 수 있습니다.

이 포스트가 도움이 되길 바랍니다! 다른 질문이 있으면 언제든지 알려주세요. 😊





오늘의 이야기

공공데이터를 사용하여 Python으로 데이터 수집  처리하기

실행결과 예시


 
안녕하세요! 오늘은 공공데이터를 활용하여 Python을 사용해 데이터를 수집하고 처리하는 방법에 대해 소개해드리려고 합니다. 이번 예제에서는 http://apis.data.go.kr/1471000/MdcinGrnIdntfcInfoService01/getMdcinGrnIdntfcInfoList01 API를 사용하여 의약품 정보를 가져오는 과정을 다룹니다.

준비물

  1. Python 설치
  2. requests 라이브러리 설치

먼저, requests 라이브러리를 설치합니다:



sh




pip install requests



API 키 발급

공공데이터 포털에서 API 키를 발급받아야 합니다. 발급받은 키를 활용하여 데이터를 요청합니다.

코드 예제

다음은 API를 호출하고 응답 데이터를 처리하는 Python 예제 코드입니다:



python




import requests

# API URL과 키 설정
api_url = "http://apis.data.go.kr/1471000/MdcinGrnIdntfcInfoService01/getMdcinGrnIdntfcInfoList01"
api_key = "YOUR_API_KEY" # 여기서 API 키를 입력하세요.

# 요청 파라미터 설정
params = {
'serviceKey': api_key,
'numOfRows': 10,
'pageNo': 1,
'type': 'json'
}

# API 호출
response = requests.get(api_url, params=params)

# 응답 상태 확인
if response.status_code == 200:
data = response.json()
# 응답 데이터 처리
items = data.get('body', {}).get('items', [])
for item in items:
print(f"품목명: {item.get('ITEM_NAME')}, 성분명: {item.get('MATERIAL_NAME')}")
else:
print("API 요청 실패:", response.status_code)



주요 단계

  1. API URL 및 키 설정: 발급받은 API 키를 사용하여 요청 URL을 구성합니다.
  2. 요청 파라미터 설정: 필요한 파라미터를 설정하여 API 요청을 준비합니다.
  3. API 호출: requests.get() 메서드를 사용하여 API 호출을 수행합니다.
  4. 응답 상태 확인: 응답 상태 코드를 확인하여 요청이 성공적으로 처리되었는지 확인합니다.
  5. 응답 데이터 처리: 응답 데이터를 JSON 형식으로 파싱하여 필요한 정보를 추출합니다.

이 예제에서는 공공데이터 포털의 API를 사용하여 의약품 정보를 가져오고, 이를 Python으로 처리하는 방법을 보여줍니다. API를 활용하면 다양한 공공데이터를 쉽게 사용할 수 있으니, 여러분도 한번 시도해 보세요!





오늘의 이야기


#스하리1000명프로젝트

오늘 내가 만든앱 하나 알려주고 싶어, 이 앱은 알림수집기 라고 이름을 붙였는 데,
내 폰에 표시 되는 알림을 읽어서 내가 지정한 단어가 들어 있고, 지출기록을 남겨야 하는 알림이
있으면 수집하고, 카카오톡으로 친구에게 전달해 주는 기능을 구현해 줄꺼야. 📲

이번 패치에서는 하루 한번 지정한 시간에 나에게 알림(노티) 하도록 기능을 추가 했어. 🙏
한번 써보고 불편한 거 있으면 말해줘.

앱 바로가기
👉 https://play.google.com/store/apps/details?id=com.nari.notify2kakao





오늘의 이야기

Android Foreground Services 사용법


good job



 


안녕하세요! 이번 포스트에서는 Android Foreground Services에 대해 알아보겠습니다. Foreground Service는 사용자가 앱과 상호작용하지 않더라도 백그라운드에서 지속적으로 실행되어야 하는 작업을 수행하는  사용됩니다. 아래는 Foreground Service 설정 방법에 대한 자세한 설명입니다.


1. 서비스 클래스 생성


먼저 Service를 상속받는 서비스 클래스를 정의합니다.



kotlin




class MyForegroundService : Service() {
private lateinit var notification: Notification

override fun onCreate() {
super.onCreate()
startForeground(1, createNotification())
}

private fun createNotification(): Notification {
val builder = NotificationCompat.Builder(this, "channel_id")
.setContentTitle("Foreground Service")
.setContentText("This is a foreground service")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(PendingIntent.getActivity(this, 0, Intent(this, MainActivity::class.java), 0))
.setAutoCancel(false)

// android api 26 이상의 경우 필요
val channel = NotificationChannel("channel_id", "Channel Name", NotificationManager.IMPORTANCE_DEFAULT)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)

return builder.build()
}

override fun onBind(intent: Intent): IBinder? {
return null
}

override fun onDestroy() {
super.onDestroy()
stopForeground(true)
}
}




2. 서비스 시작


서비스를 시작하려면 액티비티나 프래그먼트에서 다음과 같이 호출합니다.



kotlin




val serviceIntent = Intent(this, MyForegroundService::class.java)
// android api 30 이상의 경우
startForegroundService(serviceIntent)




3. AndroidManifest.xml 설정


AndroidManifest.xml 파일에 서비스 선언을 추가합니다.



xml




<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />

<application
...

<service
android:name=".MyForegroundService"
android:exported="false"
android:foregroundServiceType="connectedDevice"
/>
</application>




4. Notification Channel 생성


앱이 Android Oreo(API 레벨 26) 이상을 타겟으로 하는 경우, Notification Channel을 생성해야 합니다.



kotlin




if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel("channel_id", "Channel Name", NotificationManager.IMPORTANCE_DEFAULT)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(channel)
}




5. Deprecated 메서드 대체


stopForeground 메서드가 deprecated 되었기 때문에, 대신 stopSelf 또는 stopService 메서드를 사용합니다.



kotlin




override fun onDestroy() {
super.onDestroy()
stopSelf()
}




6. 안드로이드 생명 주기와 서비스 관리


적절한 시점에 startService와 stopService를 호출하여 서비스의 시작과 종료를 관리해야 합니다. 예를 들어:



  • onCreate() 또는 onStart(): 앱이 처음 실행될 때.

  • onDestroy(): 앱이 종료될 때.


 포스트가 Android Foreground Services 설정과 관리에 도움이 되길 바랍니다. 궁금한 점이 있으면 언제든지 댓글로 남겨주세요! 😊








오늘의 이야기


#스하리1000명프로젝트,
Lost in Korea?即使您不会说韩语,这个应用程序也可以帮助您轻松出行。
只需说出您的语言即可 - 它会翻译、搜索并以您的语言显示结果。
非常适合旅行者!支持英语、日语、中文、越南语等10多种语言。
现在就试试吧!
https://play.google.com/store/apps/details?id=com.billcoreatech.opdgang1127




오늘의 이야기



#스치니1000프로젝트 #재미 #행운기원 #Compose #Firebase

🎯 야 너 토요일마다 로또 확인하냐?
나도 맨날 “혹시나~” 하면서 봤거든 ㅋㅋ

근데 이제는 그냥 안 해
AI한테 맡겼어 🤖✨

그것도 구글 Gemini로다가!

그래서 앱 하나 만들었지
👉 “로또 예상번호 by Gemini” 🎱

AI가 분석해서 번호 딱! 뽑아줌
그냥 보고 참고만 하면 됨

재미로 해도 좋고…
혹시 모르는 거잖아? 😏


https://play.google.com/store/apps/details?id=com.billcorea.gptlotto1127




2026/04/13

오늘의 이야기


#스하리1000명프로젝트,
Às vezes é difícil conversar com trabalhadores estrangeiros, certo?
Fiz um aplicativo simples que ajuda! Você escreve na sua língua e os outros veem na deles.
Ele é traduzido automaticamente com base nas configurações.
Muito útil para bate-papos fáceis. Dê uma olhada quando tiver uma chance!
https://play.google.com/store/apps/details?id=com.billcoreatech.multichat416




오늘의 이야기

코인 4.0: 코틀린 멀티플랫폼 개발을 위한 강화된 의존성 주입


koin 4.0 ?





• 코틀린 2.0을 기반으로 구축된 코인 4.0은 플랫폼 전반에 걸쳐 일관된 UUID 생성, 향상된 컨텍스트 통과, 보다 스레드 안전하고 성능이 뛰어난 컬렉션을 포함한 다양한 개선 사항을 도입한다.

• 여전히 실험적인 새로운 코인-푸 DSL은 구성자 DSL의 한계를 해결하고 "싱글오프" API에 대한 더 나은 통일된 경험을 제공하는 것을 목표로 한다.

• 코인 4.0은 ViewModel API에 주요 업그레이드를 제공하며 안드로이드, 제트팩 컴포즈 및 기타 프레임워크에 대한 통합이 개선된 완전 멀티플랫폼 접근 방식으로 전환합니다.

• 컴포즈 뷰모델 내비게이션 지원은 인수 주입 개선, 컴포즈 내비게이션 1.7과의 호환성 등을 포함해 도입된다.

• 새로운 그래들 패키지인 koin-androidx-startup은 AndroidX Startup으로 스타트업 프로세스를 최적화하여 부하 시간을 최대 40%까지 줄입니다.

• 코인의 컴포즈 API는 플랫폼 전반에 걸쳐 더 쉬운 통합 및 코드 재사용을 가능하게 하는 더 많은 멀티플랫폼 기능에 대한 지원을 추가하기 위해 재작업되었습니다.

https://blog.insert-koin.io/koin-4-0-official-release-f4827bbcfce3



 


Koin 4.0 — Official Release


The Koin team is excited to announce the release of Koin 4.0, a major update that brings improvements for Kotlin, Compose & Android


blog.insert-koin.io




 





오늘의 이야기

Python을   이용한   Firebase   Realtime   Database   생성   및   Android   Studio를   통한   데이터   읽기 앱 개발자로 살아보기 안녕하세요!   오늘은...