2016-03-31 21 views
1

ドキュメントに引用されているとおり、ユーザをリストに保存します。ユーザーは、パスワードとFacebookプロバイダの両方でログオンできます。 (他のプロバイダが後で来るかもしれません)再起動後もFirebaseリストに追加された新しいユーザを知る

次に、私は新しいリストの項目を聞いて、新しい項目の場合に私に電子メールを送るnodejsアプリを持っています。

これはfirebaseで簡単ですが、child_addedイベントリスナーを追加するだけです。しかし、私のアプリが更新/クラッシュなどの理由で再起動する可能性があるため、アプリを再起動するたびにすべてのユーザーとメールを受け取る必要はありません。だから私はちょうど電子メールを送信するために使用されている最新のuserIdを保存します。

var retrieveLatestAccountNotified = function() { 
    ref.child("server-state").child("email-account").once("value", function (snapshot) { 
     user = snapshot.val(); 
     console.log("Latest User Id : " + user); 
     fetchUser(user); 
     //fakeUser(""); 
    }, function (errorObject) { 
     console.log("The read failed: " + errorObject.code); 
    }); 
}; 


var fetchUser = function (latestUserId) { 
    ref.child("users").orderByKey().startAt(latestUserId).on("child_added", function (snapshot, prevChildKey) { 
     if (snapshot.key() !== latestUserId) { 
      var newUser = snapshot.val(); 
      console.log(newUser); 
      sendEmail.newAccountEmail(ses, newUser, snapshot.key(), function (err, data) { 
       if (err) 
        throw err; 
       console.log('Email sent:'); 
       console.log(data); 
       ref.child("server-state").child("email-account").set(snapshot.key()); 
      }); 
     } 

    }, function (errorObject) { 
     console.log("The read failed: " + errorObject.code); 
    }); 
}; 

問題は、FBが選択したプロバイダによって異なるuserIdタイプを生成するため、私の仕組みが機能しないということです。

これに対処するにはどうすればよいですか?

  • ユーザーが作成されたときにすべてのユーザーに、子供(CREATION_DATE)を追加 =>は、余分な追加多くのクライアントがユーザーを追加すると、この機構は
  • 各クライアントの実装で使用する必要があります =>優先順位を追加ユーザー
  • ユーザーが を通知された保存し、別のリストを追加で情報=>両方の完全なリスト上のループに必要

どれでも教育を受けた命題は大歓迎です!

答えて

3

このために使用される一般的なアプローチは、あなたの#3に近い:

ユーザーは=>

完全なリストの両方にループに必要と通知された保存し、別のリストを追加

通常、電子メール通知を送信するためのキューを追加します。このキューは純粋に通知を送信するためのものであるため、サーバーは完了後にその中からアイテムを削除します。最も単純な形式で

ref.child('emailNotificationQueue').on('child_added', function(snapshot) { 
    sendEmailToAnthony(snapshot.val(), function() { 
    snapshot.ref().remove(); 
    }); 
}); 

スケーラビリティおよび他の多くの理由から、あなたはfirebase-queueを使用する場合があります。しかし、それはそのようなループの(美しく)スープされたバージョンです。

あなたはキューに二つのアプローチをとることができます。

  1. アプリは/usersに新しいユーザと/emailNotificationQueueへの通知を書き込みます。これは通常動作しますが、悪意のあるクライアント(またはコーディングミス)が1つを書きますが、もう1つは書き込まないと、不快なレース/エラー状態になります。あなたはこれらに対して保護することができますが、時には簡単なアプローチがあります。

  2. あなたのアプリは/newUserQueueに新しいユーザーを書き込みます。サーバーはそこからそれらを読み取り、のメールを/usersに追加します。

+0

私はfirebase-queueについて知りましたが、それは強力なようです。すべてのトピックについて個別のキューを作成し、タスクにspecIdを追加することをお勧めしますか? – Anthony

+0

これは実際にバックエンドコードをどのように構築するか、タスクが十分に異なるかどうかによって異なります。最初の「createUser」をタスクにして、他の「サブタスク」をファンアウトすることもできます。しかし、私は通常、よりシンプルなシステムを好みます。 –

1

電子メールが最後にユーザオブジェクトで送信されたときにタイムスタンプを保存し、タイムスタンププロパティを持つ子によってクエリを保存できます。このアプローチには、すべてのユーザーのメールを初めて送信する可能性があるという1つの問題があります。

var fetchUser = function (last_email_sent_ts) { 
    // as email_sent_ts will only have valid value when email is sent 
    // if we query by email_sent_ts equals to null shall return all the 
    // values that are missed during the restart 
    ref.child("users") 
     .orderByChild("email_sent_ts") 
     .equalTo(null) 
     .on("child_added", success , error);  

    function success(snapshot, prevChildKey) {    
     var newUser = snapshot.val(); 

     if (newUser.email_sent_ts === last_email_sent_ts) return; 

     sendEmail.newAccountEmail(ses, newUser, snapshot.key(), emailCallback); 

     function emailCallback(err, data) { 
      if (err) throw err; 

      var email_sent_ts = new Date().getTime(); 

      ref.child("users") 
       .child(snapshot.key()) 
       .child('email_sent_ts').set(email_sent_ts); 

     }          
    } 
} 
関連する問題