Archive/잡동사니

[iOS] firebase CRUD 기초 및 유의사항

lgvv 2021. 5. 1. 02:09

첫 시작은 메인 스토리보드와 전체 소스코드를 제공해주겠다.

기본적인 설치는 공식문서 찾아보거나 다른 분 글 보면서 직접 해보기.

viewController 하나만 존재하고 매우매우 기초사항만 다뤘다.

스토리보드 - View 1개

//
//  ViewController.swift
//  Realtime
//
//  Created by Hamlit Jason on 2021/04/30.
//

import UIKit
import Firebase

class ViewController: UIViewController {

    
    var ref: DatabaseReference!

    @IBOutlet weak var label: UILabel!
    
    var todos = [String]()
    var todos2 = [String:String]()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func write(_ sender: Any) {
        let dialog = UIAlertController(title: "추가", message: nil, preferredStyle: .alert)
        
        dialog.addTextField()
        
        let okAction = UIAlertAction(title: "ok", style: .default) {
            (action : UIAlertAction) in
            if let newTodo = dialog.textFields?[0].text {
                print("입력할 내용 :\(newTodo)")
                self.ref = Database.database().reference() // 내 데이터베이스의 주소를 넣어준다.
                
                self.todos.append(newTodo)
                self.todos2 = ["lgvv":newTodo]
                
                let itemRef = self.ref.child("list")
                itemRef.setValue(self.todos)
                print(self.todos)

                self.ref.child("users/lgvv/username").setValue(self.todos2)
                print("data access")
            }
        }
        dialog.addAction(okAction)
        present(dialog, animated: true)
    }
    
    @IBAction func Read(_ sender: Any) {
        self.ref = Database.database().reference()
        ref.child("users/lgvv/username").observeSingleEvent(of: .value) { (DataSnapshot) in
            // get user value
            let value = DataSnapshot.value as? NSDictionary
            let username = value?["lgvv"] as? NSString ?? ""
            
            print(username)
        }
        
        let userRef = ref.child("users")
        
        userRef.observe(DataEventType.value, with: { (snapshot) in // DataEventType 사용하면 write이나 Read 등 데이터가 변경되면 호출된다.
            let postDict = snapshot.value as? [String : AnyObject] ?? [:]
            print(type(of: postDict))
            print(postDict)
          // ...
        })
        
    }
    
    @IBAction func Update(_ sender: Any) {
        self.ref = Database.database().reference()
        
        guard let key = ref.child("list").childByAutoId().key else { return }
        
        let dialog = UIAlertController(title: "추가", message: nil, preferredStyle: .alert)
        
        dialog.addTextField()
        
        let okAction = UIAlertAction(title: "ok", style: .default) {
            (action : UIAlertAction) in
            if let newTodo = dialog.textFields?[0].text {
                print("입력할 내용 :\(newTodo)")
                self.ref = Database.database().reference() // 내 데이터베이스의 주소를 넣어준다.
                
                self.todos.append(newTodo)
                self.todos2 = ["lgvv":newTodo]
                
                let childUpdates = ["/list/": self.todos]
                let childUpdates2 = ["/users/": self.todos2]

         
                self.ref.updateChildValues(childUpdates)
                self.ref.updateChildValues(childUpdates2)
                //let itemRef = self.ref.child("list")
                //itemRef.setValue(self.todos)
                print(self.todos)

                //self.ref.child("users/lgvv/username").setValue(self.todos2)
                print("data access")
            }
        }
        dialog.addAction(okAction)
        present(dialog, animated: true)
        /*
        let post = ["uid": userID,
                    "author": username,
                    "title": title,
                    "body": body]
    */
    }
    
    
    @IBAction func delete2(_ sender: Any) {
        
        self.ref = Database.database().reference()
        
        
        let dialog = UIAlertController(title: "삭제", message: nil, preferredStyle: .alert)
        
        dialog.addTextField()
        
        let okAction = UIAlertAction(title: "ok", style: .default) {
            (action : UIAlertAction) in
            if let newTodo = dialog.textFields?[0].text {
                print("입력할 내용 :\(newTodo)")
                self.ref = Database.database().reference() // 내 데이터베이스의 주소를 넣어준다.
                
                self.todos.append(newTodo)
                self.todos2 = ["lgvv":newTodo]
                
                self.ref.child("users").removeValue { (_: Error?, DatabaseReference) in
                    print("delete")
                }

                print(self.todos)

                print("data access")
            }
        }
        dialog.addAction(okAction)
        present(dialog, animated: true)

    }
        
    
    
    
    
}

GoogleService-Info 이 파일의 이름이 정확하게 일치해야한다.

파이어베이스 공식 문서에서는 여기로 가져올 때, copy를 하지 않아야 유일성이 유지된다나? 아무튼 그걸 권장한다고 들었는데, 유일성은 개뿔...

그냥 복사해서 써라. 그래야 속 안썩인다.

만약 복사 안하고 연결만 해두면 예를 들면 [다운로드] 위치에 있던 이 파일을 없애거나 다른 곳으로 옮기면 작동되지 않는다.

GoogleService-Info 파일 연결의 주의점

파이어베이스 wirte시 코드 간략히 적어보자면,

이게 어떤게 어렵나면 우선 사진에는 나오진 않았지만 컨트롤러 위에

import Firebase와

var ref: DatabaseReference

이 두 코드가 선언되어 있다.

self.ref로 사용하는데 내 데이터 베이스 주소를 주는 코드라고 한다.

setValue가 코드를 추가하는거라고 하니 꼭 잊지 말기.

경로를 직접 줄수도 있는데, 하위노드가 전부 덮여질 수도 있음으로 변수와 그걸 확인하는 exist() 그리고 로그인을 확인하는 코드들과 함께 사용하면 두배로 좋을 것이다.

write

 

다음은 읽는 법에 대해서 알아보자

읽는 법도 쉽다

내 파이어베이스 주소 가져와서 스냅샷 찾아오는건데 한번 읽는 방법과

postDict처럼 여러번 변경될때마다 읽는 코드가 2가지가 있는데

postDict는 아무래도 채팅앱 구현할 때 상당히 유용할 예정이다.

근데 postDict가 딕셔너리 타입이라 저렇게 냅두면 사용하기가 불편하다.

pythonq.com/so/ios/1346267 여기 링크를 참고하여 for문을 돌려서 사용할 수 있다.

 

Read

 

다음은 업데이트다

업데이트도 어렵지 않다. 그냥 주의할 점은 노드가 덮여지는 것만 잘 막으면 된다.

exist() 같은거 잘 활용하자 파베 공식문서에 잘 나와있다.

update코드다 이건

 

이번에는 삭제인데 딜리트가 걍 제일 간단한

removeValue하거나 아니면 업뎃이나 setValue에 nil 넣는 방법도 있다.

근데 nil 넣는게 완전히 날리는게 아니라 더 안전할 듯 싶다.

 

delete