2016-05-10 8 views
0

私はすでにこれのために実際のアプリケーションのすべてを終了しました。バックエンドをセットアップするだけです。私は、Parseはもはや事ではないので、Firebaseが最高の解決策であると考えました。私が欲しかったのは:Firebaseデータベースヘルプ - Swift

プロファイルのあるユーザー - これらのプロファイルは、追加された友人から見ることができますが、実際のプロファイルの所有者のみが編集(書込み)できます。


私はFirebase Docsを読みましたが、これを行う方法を実際には分かりません。彼らは似たようなことをしない1つのSwiftアプリケーションの例と、Obj Cの1つのtwitterのものだけを構築しています。彼らのドキュメントのすべてはまだそれが頻繁に更新されていないと思うSwiftのprintlnを持っています。


誰もがこの良い例やチュートリアルを持っていますか?私は物事を検索しようとしているが、何も私が欲しいものに似ているほどではない。私は各ユーザのためにdbを設定し、SwiftのFirebaseを使って実際にアクセスする方法をもっと探しています。

+1

私はSwift + Firebaseを使用してソーシャルアプリ全体を作成しました。私はあなたが達成したいことをより正確に説明しなければならないと思います。私のアプリ(https://itunes.apple.com/jp/app/impether/id1084468692)を見て、これがあなたが探しているものであれば何か問題があるかどうかを教えてください。それから私たちが本番で使っているコードスニペットを使って完全な答えを書いてみましょう。それで、あなたが達成したいことに関する何らかのドキュメンテーションになるかもしれません:) – pkacprzak

+0

Hey!私はそれをダウンロードして試しました。素晴らしく見える!独自のプロファイルを持っている複数のユーザーが、そのユーザーだけが書き込みでき、友人が閲覧することができます。それはまさに私が探していることです。あなたが答えを書くなら、私は大いに感謝します。 @pkacprzak – JohnV

答えて

5

あなたの質問に私のコメントで書いたように、この回答はSwift + Firebaseを使用して実際のソーシャルアプリImpetherで行っていることに基づいています。

データ構造

あなたは、単一のユーザーのために、以下の情報を格納したいと仮定しましょう:

  • メール
  • ユーザ名
  • 人のフォロワーから以下の特定のユーザー
  • をフォローしているユーザーの数 - いくつかの追加のテキスト
  • - 自分のアバター
  • バイオのURL - 特定のユーザが
  • avatar_urlを次の人の数

FirebaseにはすべてJSONオブジェクトが格納されているので、上記の構造体をusers/$userIdのようなパスのノードに格納することができます。$userIdはFirですebase単純な電子メール/パスワードFirebase認証を使用する場合、登録ユーザごとに作成されるユーザUID。

Firebaseメール/パスワード認証は、そのドキュメントに記述されている:OBJの-Cとスウィフトの両方のスニペットがあること https://www.firebase.com/docs/ios/guide/user-auth.html https://www.firebase.com/docs/ios/guide/login/password.html

注意してください。 Firebaseのドキュメンテーションが本当に素晴らしいと私は知っています。

この回答のために、ユーザー名がjack、FirebaseユーザーのUIDがjack_uid(実際はFirebaseによって生成された文字列)になっているものとします。

次に、このユーザーのためのサンプルデータは、パスusers/jack_uid下店舗となり、次のようになります。ユーザーが署名したい場合

{ 
    "email" : "[email protected]", 
    "username" : "jack", 
    "name" : "Jack", 
    "followers" : 8, 
    "following" : 11, 
    "avatar_url" : "http://yourstoragesystem.com/avatars/jack.jpg", 
    "bio" : "Blogger, YouTuber", 
} 

Firebaseメール/パスワード認証は、本当によく働くが、のは、正直言ってみましょうアプリには、彼のアカウントを登録している間に彼が与えた彼の電子メールよりも彼のユーザ名を使う方がずっと良いです。

これを行うために、ユーザー名からユーザーIDへのマッピングを保存することにしました。ユーザーは、ユーザー名とパスワードをログインフォームに入力すると、そのマッピングを使用してユーザーIDを取得し、ユーザーIDとパスワードを使用してユーザーに署名しようとします。

マッピングはパスusername_to_uidの下で、たとえば保存することができ、次のようになります。

次に、このようになりますと、それは新しいアカウントの登録とすぐに行うのが成功したかもしれプロファイルを作成
{ 
    "sample_username_1": "firebase_generated_userid_1", 
    "sample_username_2": "firebase_generated_userid_2", 
    ... 
    "jack": "jack_uid", 
    "sample_username_123": "firebase_generated_userid_123" 
} 

(これをスニペットは)私たちが生産に使用正確なコードに非常に近いです。これに加えて

func createProfile(uid: String, email: String, 
        username: String, avatarUrl: String, 
        successBlock:() -> Void, errorBlock:() -> Void) { 

    //path to user data node 
    let userDataPath = "https://stackoverflow.com/users/\(uid)" 

    //path to user's username to uid mapping 
    let usernameToUidDataPath = "/username_to_uid/\(username)" 

    //you want to have JSON object representing user data 
    //and we do use our User Swift structures to do that 
    //but you can just create a raw JSON object here. 
    //name, avatarUrl, bio, followers and following are 
    //initialized with default values 
    let user = User(uid: uid, username: username, name: "", 
        avatarUrl: avatarUrl, bio: "", 
        followers: 0, following: 0) 

    //this produces a JSON object from User instance 
    var userData = user.serialize() 
    //we add email to JSON data, because we don't store 
    //it directly in our objects 
    userData["email"] = email 

    //we use fanoutObject to update both user data 
    //and username to uid mapping at the same time 
    //this is very convinient, because either both 
    //write are successful or in case of any error, 
    //nothing is written, so you avoid inconsistencies 
    //in you database. You can read more about that technique 
    //here: https://www.firebase.com/blog/2015-10-07-how-to-keep-your-data-consistent.html 

    var fanoutObject = [String:AnyObject]() 
    fanoutObject[userDataPath] = userData 
    fanoutObject[usernameToUidDataPath] = uid 

    let ref = Firebase(url: "https://YOUR-FIREBASE-URL.firebaseio.com/images") 
    ref.updateChildValues(fanoutObject, withCompletionBlock: { 
     err, snap in 
     if err == nil { 
      //call success call back if there were no errors 
      successBlock() 
     } else { 
      //handle error here 
      errorBlock() 
     } 
    }) 
} 

あなたはおそらく、各ユーザのための彼のフォロワーのリストと、彼は次のユーザーのリストを個別に保存します。

{ 
    "firebase_generated_userid_4": true, 
    "firebase_generated_userid_14": true 
} 

これは、我々は我々のアプリ内の値のセットを格納する方法である:それは次のようになります。例えばこれは、ちょうどfollowers/jack_uidようなパスでユーザIDを格納することによって行うことができます。それは本当にそれを更新し、いくつかの値があるかどうかを確認するのは本当にユーザーなので、非常に便利です。

フォロワーの数をカウントするために、このカウンターをユーザーのデータに直接入れます。これにより、カウンターの読み取りが非常に効率的になります。しかし、このカウンタを更新するトランザクションの書き込みを使用して必要とし、アイデアがほぼ正確にここに私の答えと同じです:Upvote/Downvote system within Swift via Firebase

読み取り/書き込み権限

あなたの質問の一部は、あなたが保存したデータへのアクセス権をどのように処理するかです。良いニュースは、Firebaseがここで非常に良いということです。 Firebaseのダッシュボードに行くと、Security&Rulesという名前のタブがあります。これはあなたのデータへのアクセス権を制御する場所です。

Firebaseルールの優れた点は、宣言的であり、使用や保守が非常に簡単なことです。しかし、純粋なJSONにルールを書き込むことは、基本ルールをより大きなルールに組み込むか、単純なアプリケーションを作成し、Firebaseデータベースに保存するデータがますます大きくなる場合に、それらを制御するのは非常に難しいため、最良のアイデアではありません。幸運なことに、FirebaseチームはBoltを書いています。これはあなたが非常に簡単に必要なすべてのルールを書くことができる言語です。

まずセキュリティに関するFirebaseのドキュメントを読むことをお勧めします。特に、ノードへのアクセス許可はその子の許可にどのように影響しますか。その後、あなたはここでボルトを見てみることができます:

//global helpers 
isCurrentUser(userId) { 
    auth != null && auth.uid == userId; 
} 

isLogged() { 
    auth != null; 
} 

//custom types, you can extend them 
//if you want to 
type UserId extends String; 
type Username extends String; 
type AvatarUrl extends String; 
type Email extends String; 

type User { 
    avatar_url: AvatarUrl, 
    bio: String, 
    email: Email, 
    followers: Number, 
    following: Number, 
    name: String, 
    username: Username, 
} 

//user data rules 
path /users/{$userId} is User { 
    write() { isCurrentUser($userId) } 
    read() { isLogged() } 
} 

//user's followers rules 
//rules for users a particular 
//user follows are similar 
path /followers/{$userId} { 
    read() { isLogged() } 
} 

path /followers/{$userId}/{$followerId} is Boolean { 
    create() { isCurrentUser($followerId) && this == true } 
    delete() { isCurrentUser($followerId) } 
} 

//username to uid rules 
path /username_to_uid { 
    read() { true } 
} 

path /username_to_uid/{$username} is UserId { 
    create() { isCurrentUser(this) } 
} 

一番下の行があることである:

https://www.firebase.com/docs/security/bolt/guide.html https://www.firebase.com/blog/2015-11-09-introducing-the-bolt-compiler.html https://github.com/firebase/bolt/blob/master/docs/guide.md

は、たとえば、我々は次のようなユーザーデータを管理するためのルールを使用しますBoltを使用してルールを作成した後、Boltコンパイラを使用してJSONにコンパイルし、コマンドラインツールを使用してFirebaseにデプロイするか、ダッシュボードに貼り付けることができます。また、ダッシュボードのSimulatorタブのツールを使用してルールをテストすることもできます。

概要

私にとってFirebaseは、あなたが望むシステムを実装するための素晴らしいツールです。しかし、私は単純な機能から始め、Firebaseの使い方を学ぶことをお勧めします。たとえばInstagramのような機能を持つソーシャルアプリを実装することは、特にそれを正しく実行したい場合は非常に大きな課題です。すべての機能をすばやくそこに置くことは魅力的ですが、Firebaseでは比較的簡単に行うことができますが、ここに。

また、時間をかけて筆記具に投資してください。たとえば、本番用とテスト用の2つのFirebaseデータベースがあります。これは、ユニットテストとUIテストを効率的に作成する場合には非常に重要です。

また、最初から許可ルールを作成することをお勧めします。後でそれらを追加することは魅力的かもしれませんが、かなり圧倒的かもしれません。

最後に、Firebaseブログに従ってください。彼らは定期的に投稿し、最新の機能やアップデートで最新の情報を得ることができます。ファンアウト技術を使って同時書き込みを使用する方法を学びました。

+0

@pkacprxakあなたも構造体を表示できますか?あなたの答えはすばらしかった、私はそんなに学んだ。 –

+0

@TarvoMäesepp確かに、あなたはどちらを見たいですか? Btwあなたの前のコメントは(何とか削除された)Twitterに上陸しました.Johel Spolskyはそれを好きでした。 – pkacprzak

+0

ええと..誰かが心から書いた私の以前の深遠なコメントを好きではなかった:) しかし、私はユーザー '構造'を意味する。そして、そのようなプロジェクトをSQLに適用した場合の利点は何だと思いますか? –