2017-12-09 18 views
0

데이터를 저장하기 위해 Firebase를 사용하고 있습니다. Firebase 메소드와 메소드를 분리하려고합니다. 예를 들어 나는 "FirebaseMethodsHelper"라는 클래스를 만들었고 모든 Firebase 메소드를 작성하려고합니다. 예를 들어, "getAllUsers"메소드는 모든 사용자를 목록으로 반환해야합니다. 유일한 문제는 작동하지 않습니다.Android firebase가 null이 됨

제가 잘못하고있는 것을 알고 있습니다. 그렇다면 제발 저를 도울 수 있습니다.

조각

public class MyPlayListFragment extends Fragment { 
    private FirebaseDatabase refToVideos; 
    private FirebaseUser currentUser; 
    private ArrayList<Video> videosList; 
    private VideoViewAdapter adapter; 
    private RecyclerView rvVideos; 
    private List<Video> checkList; 


public MyPlayListFragment() { 
    // Required empty public constructor 
} 


@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View v = inflater.inflate(R.layout.fragment_my_play_list, container, false); 
    rvVideos = (RecyclerView)v.findViewById(R.id.rvVideos); 

    return v; 
} 

@Override 
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
    super.onViewCreated(view, savedInstanceState); 
    videosList = new ArrayList<>(); 
    refToVideos = FirebaseDatabase.getInstance(); 
    currentUser = FirebaseAuth.getInstance().getCurrentUser(); 

    FirebaseMethodsHelper fmh = new FirebaseMethodsHelper(); 


    checkList = fmh.getAllVideosFromDB(currentUser); 
    if(checkList != null) 
    Log.d("checkList",checkList.toString()); 

FirebaseMethodHelper 클래스 I 이유는 잘 모릅니다 만, 항상 null를 돌려

public class FirebaseMethodsHelper { 
private FirebaseDatabase databaseRef; 
private ArrayList<User> usersList; 
private ArrayList<Video> videosList; 



    public List<Video> getAllVideosFromDB(FirebaseUser currentUser){ 
     databaseRef = FirebaseDatabase.getInstance(); 
     databaseRef.getReference(Params.VIDEOS).child(currentUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       for (DataSnapshot snapshot : dataSnapshot.getChildren()){ 
        videosList.add(snapshot.getValue(Video.class)); 
       } 
      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 

      } 
     }); 


    return videosList; 
    } 
} 

.

답변

2

이것은 비동기 웹 API의 일반적인 문제입니다. now을 아직로드 할 수 없습니다. 아직로드되지 않았습니다.

Firebase 데이터베이스 (그리고 최신 웹 API) 데이터는 비동기 적으로로드됩니다. 시간이 오래 걸릴 수 있습니다. 사용자를 위해 응용 프로그램 응답 없음 대화 상자로 연결되는 데이터를 기다리는 대신 보조 응용 프로그램에서 데이터를로드하는 동안 기본 응용 프로그램 코드가 계속됩니다. 그런 다음 데이터를 사용할 수있게되면 onDataChange() 메서드가 호출되고 데이터를 사용할 수 있습니다.

이렇게하면 앱의 흐름이 바뀝니다. 청취자

를 부착 한 후 청취자

를 장착하기 전에

: 다음과 같은 순서로 인쇄됩니다이 코드를 실행

public List<Video> getAllVideosFromDB(FirebaseUser currentUser){ 
    databaseRef = FirebaseDatabase.getInstance(); 
    System.out.println("Before attaching listener"); 
    databaseRef.getReference(Params.VIDEOS).child(currentUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      System.out.println("Got data"); 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 
      throw databaseError.toException(); // don't ignore errors 
     } 
    }); 
    System.out.println("After attaching listener"); 
} 

이 볼 수있는 가장 쉬운 방법은 몇 가지 로그 문을 배치하는 것입니다 데이터가 있습니다.

Th 아마도 당신이 예상했던 것과 다르지 만 반환 할 때 배열이 비어있는 이유를 정확하게 설명합니다.

대부분의 개발자를위한 초기 응답은이 비동기 동작을 "수정"하는 것입니다. 웹을 비동기 적으로 사용하는 것이 더 빠르면 빠를수록 현대 웹 API로 생산성을 높일 수있는 방법을 배울 수 있습니다.

이 비동기 패러다임의 문제를 재구 축하기가 가장 쉽다는 것을 알게되었습니다. "먼저 모든 비디오를 가져 와서 로그"라고 말하지 않고 문제를 "모든 비디오를 가져 오기 시작합니다. 비디오가로드되면 로그에 남김"으로 표시합니다.

즉, 동영상이 필요한 모든 코드는 onDataChange() 안에 있어야합니다 (또는 내부에서 호출 됨). 예 : 이전에 비동기 API를 처리하지 않은 개발자는 일반적인 문제입니다.따라서, 이미 거기 주제에 꽤 몇 가지 질문을하고, 나는 당신이 너무 그들을 밖으로 검사 추천했습니다 :

+0

답변 해 주셔서 감사합니다. 메신저 그 링크를 확인합니다! –

1

videosList 목록이 아직 초기화되지 않아 null을 반환합니다. 또한 메서드에서 목록을 반환하는 방법이 잘못되었습니다. firebase 호출은 비동기식이므로 데이터를 사용할 수있는 시점을 제어 할 수 없으므로 메서드가 null (목록이 초기화되지 않은 경우) 또는 빈 목록 (사용자가 초기화 한 경우)을 반환합니다. 원하는대로

해결책 인터페이스 콜백을 사용하는 것, 이것은 당신의 조각에 동영상 목록을 반환합니다

public interface FirebaseCallback { 
    void listVideos(ArrayList<Video> videos); 
} 

이 방법은 호출됩니다 FirebaseMethodHelper 클래스 :

public void getAllVideosFromDB(FirebaseUser currentUser, FirebaseCallback callback){ 
    databaseRef = FirebaseDatabase.getInstance(); 
    databaseRef.getReference(Params.VIDEOS).child(currentUser.getUid()).addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      ArrayList<Video> videosList = new ArrayList<>(); 

      for (DataSnapshot snapshot : dataSnapshot.getChildren()){ 
       videosList.add(snapshot.getValue(Video.class)); 
      } 

      callback.listVideos(videosList); 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 
} 

그리고 조각에서 인터페이스를 구현하고 을 다음과 같이 메서드에 전달합니다.

+0

와우 응답, 감사합니다! –