2016-08-03 7 views
3

Firebase Server SDKとJerseyを使用して書き込み操作を実行するためにREST APIを作成しようとしています。ここで返却方法JerseyからResponeを呼び出す

私がしようとしているものです:私はしたい

APIレスポンス

の送信数Firebaseノード

  • 上のいくつかの書き込み操作を実行
    1. Initializing Firebase SDK
    2. Getting idToken from Client and Validating idToken
    3. return Firebaseの書き込み操作が成功または失敗した場合にのみ応答します。 Firebase Listenerの内部で発生します。しかし、リスナーから値を返そうとしますが、Firebaseリスナーには戻り値の型がないため、エラーが発生します。

      リスナーからの返信を返すにはどうすればよいですか?

      ここに私のコードです。

      MyEndpoint.java

      @Path("/restapi") 
      //BaseEndpoint does Authentication operations 
      public class MyEndpoint extends BaseEndpoint { 
      
          public void Authenticate(String token, AuthenticationListener authenticationResultListener) { 
           super.Authenticate(token, authenticationResultListener); 
          } 
      
          @POST 
          @Produces("application/json") 
          @Consumes(MediaType.APPLICATION_FORM_URLENCODED) 
          public Response createCommunity(@FormParam("idToken") String idToken) { 
           Authenticate(idToken, new AuthenticationListener() { 
            @Override 
            public void onAuthenticationSuccess() { 
             // The app only has access as defined in the Security Rules 
             DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/mysamplenode"); 
             ref.addListenerForSingleValueEvent(new ValueEventListener() { 
              public void onDataChange(DataSnapshot dataSnapshot) { 
               String res = dataSnapshot.getKey(); 
               //I will do some write operations on Firebase here 
               //If they complete successfuly only then I want to return api response 
               return Response.status(200).entity().build(); 
              } 
              @Override 
              public void onCancelled(DatabaseError arg0) { 
               System.out.println("DatabaseError-------------" + arg0); 
               return Response.status(500).entity("DatabaseError").build(); 
              } 
             }); 
            } 
            @Override 
            public void onAuthenticationFailure() { 
             return Response.status(403).entity("Forbidden").build(); 
            } 
           }); 
          } 
      } 
      

      BaseEndpoint.java

      public class BaseEndpoint { 
      
          public static String uid; 
      
          public void Authenticate(String token, AuthenticationListener authenticationResultListener) { 
           // idToken comes from the client app 
           FirebaseAuth.getInstance().verifyIdToken(token).addOnFailureListener(new OnFailureListener() { 
      
            @Override 
            public void onFailure(Exception arg0) { 
             System.out.println("Uid exp= " + arg0); 
             authenticationResultListener.onAuthenticationFailure(); 
            } 
           }).addOnSuccessListener(new OnSuccessListener<FirebaseToken>() { 
            @Override 
            public void onSuccess(FirebaseToken decodedToken) { 
             uid = decodedToken.getUid(); 
             System.out.println("Uid= " + uid); 
             authenticationResultListener.onAuthenticationSuccess(); 
            } 
           }); 
          } 
      } 
      
  • 答えて

    1

    だから私はFirebase SDKを推測しているが本質的に非同期です。この場合、Jersey 2.xを使用している場合はasynchronous server supportを使用できます。コールバックでAsyncResponse.resume(Response)に電話することができます。たとえば、

    @POST 
    @Produces("application/json") 
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED) 
    public void createCommunity(@FormParam("idToken") String idToken, 
               @Suspended final AsyncResponse response) { 
        Authenticate(idToken, new AuthenticationListener() { 
         @Override 
         public void onAuthenticationSuccess() { 
          DatabaseReference ref = FirebaseDatabase.getInstance() 
            .getReference("/mysamplenode"); 
          ref.addListenerForSingleValueEvent(new ValueEventListener() { 
           public void onDataChange(DataSnapshot dataSnapshot) { 
            String res = dataSnapshot.getKey();       
            response.resume(Response.status(200).entity().build()); 
           } 
           @Override 
           public void onCancelled(DatabaseError arg0) { 
            response.resume(Response.status(500).entity("DatabaseError").build()); 
           } 
          }); 
         } 
         @Override 
         public void onAuthenticationFailure() { 
          response.resume(Response.status(403).entity("Forbidden").build()); 
         } 
        }); 
    } 
    

    Jersey 1.xを使用している場合、実際には非同期オプションはありません。 CountDownLatchでフローをブロックし、コールバックにローカルResponseを割り当て、カウントダウンするだけです。

    @POST 
    @Produces("application/json") 
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED) 
    public void createCommunity(@FormParam("idToken") String idToken) { 
        Response response; 
        CountDownLatch latch = new CountDownLatch(1); 
        Authenticate(idToken, new AuthenticationListener() { 
         @Override 
         public void onAuthenticationSuccess() { 
          DatabaseReference ref = FirebaseDatabase.getInstance() 
            .getReference("/mysamplenode"); 
          ref.addListenerForSingleValueEvent(new ValueEventListener() { 
           public void onDataChange(DataSnapshot dataSnapshot) { 
            String res = dataSnapshot.getKey();       
            response = Response.status(200).entity().build(); 
            latch.countDown(); 
           } 
           @Override 
           public void onCancelled(DatabaseError arg0) { 
            response = Response.status(500).entity("DatabaseError").build(); 
            latch.countDown(); 
           } 
          }); 
         } 
         @Override 
         public void onAuthenticationFailure() { 
          response = Response.status(403).entity("Forbidden").build(); 
          latch.countDown(); 
         } 
        }); 
        latch.await(); 
        return response; 
    } 
    
    +0

    ありがとうございます。これは有望に見えますが、私は以下の依存関係を使用しています。 Jerseyを使用するためには何を変更する必要がありますか。 2.X? ' \t \t \t com.sun.jersey \t \t \t 1.9 \t \t' –

    +0

    \t \t \t ジャージーサーバーそれだけ変えるの依存関係のように単純ではありません。それでもいくつかの設定が必要です。 Jersey 2での経験がない場合は、この[Getting Started Guide](http://paulsamsotha.blogspot.com/2015/10/getting-started-with-jersey-2.html)をご確認ください。 –

    +0

    セットアップ済み今すぐJersey2.23.1。しかし、非同期呼び出しでエラーが発生しています。WARNING:サーブレットリクエストを非同期モードにしようとしましたが失敗しました。サーブレットの設定を確認してください。リクエスト処理に関係するすべてのサーブレットインスタンスとサーブレットフィルタは、非同期リクエスト処理のサポートを明示的に宣言する必要があります。 java.lang.IllegalStateException:現在のチェーンのフィルタまたはサーブレットが非同期操作をサポートしていません。 ' 解決策を見つけるのに多くの時間を費やしましたが、いずれも機能しませんでした。 –

    0

    私は少し遅れて、この質問に答えるかもしれないが、FirebaseサーバーSDKを試した後、私はあなたが同期応答を待つSDKで利用できるタスクを作成することができることを見出しました。下記のスニペットがお役に立てます:

    public class BaseEndpoint { 
    
        public static String uid; 
    
        public void Authenticate(String token, AuthenticationListener authenticationResultListener) { 
         // idToken comes from the client app 
         FirebaseToken firebaseToken = null; 
         try { 
          Task<FirebaseToken> authTask = FirebaseAuth.getInstance().verifyIdToken(token); 
          Tasks.await(authTask); 
          firebaseToken = authTask.getResult(); 
         } catch (Exception e) { 
          authenticationResultListener.onAuthenticationFailure(); 
         } 
         uid = firebaseToken.getUid(); 
         System.out.println("Uid= " + uid); 
         authenticationResultListener.onAuthenticationSuccess(); 
        } 
    } 
    
    関連する問題