根据firebase管理值事件更改Dom元素

时间:2017-08-18 01:10:50

标签: javascript firebase firebase-realtime-database firebase-admin

我在Servlet中打印了一个简单的HTML页面。这里我设置了firebase admin sdk并为路径设置了一个值事件监听器。

当事件触发时,我希望更改Div元素并在那里显示结果。

编辑:监听器确实在使用日志进行进一步测试。

但我仍然不知道如何反映div元素内部的变化,因为Listeners是异步的。这很可能是脚本无效的原因。

有人可以指导我做我应该做的事情。代码如下:

 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;

 import javax.servlet.ServletException;
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;

 import com.google.firebase.FirebaseApp;
 import com.google.firebase.FirebaseOptions;
 import com.google.firebase.auth.FirebaseCredentials;
 import com.google.firebase.database.DataSnapshot;
 import com.google.firebase.database.DatabaseError;
 import com.google.firebase.database.DatabaseReference;
 import com.google.firebase.database.FirebaseDatabase;
 import com.google.firebase.database.ValueEventListener;

 @WebServlet("/WebWaitlistViewServelet")
 public class WebWaitlistViewServelet extends HttpServlet {
private static final long serialVersionUID = 1L;

public WebWaitlistViewServelet() {
    super();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    PrintWriter pw = response.getWriter();

    try {

        String cityName=request.getParameter("city");

        String restId = request.getParameter("restid");

        String userId = request.getParameter("userid");

        if(cityName == null || restId == null || userId == null){
            System.out.println("Error getting values");
            return;
        }else{
            System.out.println(cityName+" "+restId+" "+userId);
        }


        pw.println("<HTML>");

            pw.println("<HEAD>");

                pw.println("<script>");

                    pw.println("function changePosition(position){ document.getElementById(\"positionInList\").innerHTML = position };");

                    pw.println("function changeTimeTillTurn(timetillturn){ document.getElementById(\"timeTillTurn\").innerHTML = timetillturn };");

                    pw.println("function showTimeTillTurn(){ document.getElementById(\"timeDiv\").style.display = \"visible\" };");

                    pw.println("function hideTimeTillTurn(){ document.getElementById(\"timeDiv\").style.display = \"hidden\" };");

                pw.println("</script>");

            pw.println("</HEAD>");

            pw.println("<BODY>");

                pw.println("<DIV align=\"center\">");

                    pw.println("<B>Your position in the waitlist is:</B>");

                pw.println("</DIV><br/>");

                pw.println("<DIV id=\"positionInList\" align=\"center\" style=\"color:blue\">");

                    pw.println("Loading...");

                pw.println("</DIV><br/>");

                pw.println("<DIV id=\"timeDiv\" align=\"center\">");

                    pw.println("<B>Approximate time till your turn is: </B><span id=\"timeTillTurn\" style=\"color:blue\">Loading...</span>");

                pw.println("</DIV>");

            pw.println("<BODY>");

        pw.println("</HTML>");

        pw.flush();


        InputStream is = getServletContext().getResourceAsStream("/WEB-INF/firebaseauth/firebase_admin_sdk_key.json");

        // Initialize the app with a service account, granting admin privileges
        FirebaseOptions options = new FirebaseOptions.Builder()
            .setCredential(FirebaseCredentials.fromCertificate(is))
            .setDatabaseUrl("https://restaurantrepo.firebaseio.com")
            .build();
        try {
            FirebaseApp.initializeApp(options);
        } catch (Exception e) {
            //
        }



        // As an admin, the app has access to read and write all data, regardless of Security Rules
        DatabaseReference waitlistRef = FirebaseDatabase.getInstance().getReference().child(cityName).child(restId).child("waitlist");

        Comparator<WaitlistedPerson> sortComparator = new Comparator<WaitlistedPerson>() {
            @Override
            public int compare(WaitlistedPerson lhs, WaitlistedPerson rhs) {
                //sort ascending... the bigger the time entered, the later the person has joined... thus the higher the time entered the lower the position
                //on waitlist
                if(lhs.getTimeentered()<rhs.getTimeentered()){
                    //if time entered is lower, keep the person higher in the list
                    return -1;
                }else if(lhs.getTimeentered()==rhs.getTimeentered()){
                    //if the time entered is the same, there are two cases possible
                    //1.. one person is remotely entered and one has entered at the resto POS... in this case, give priority to POS entered user
                    //2.. both people have remotely entered ... in this case, give preference to the person with lowest userid (he/she started using our app earlier)
                    //
                    //cases that will never happen are
                    //1.. two people with same userid entered remotely at same time .. can't happen as a second entry simply overwrites the old entry
                    //2.. two people with same time entered at POS ... can't happen as the resto host can only enter one party at a time..
                    if(!lhs.isRemotelyEntered() && rhs.isRemotelyEntered()){
                        //Log.d("FragmentCreate","lhs userid "+lhs.getUserid()+" lhs remotelyentered "+lhs.isRemotelyEntered());
                        //Log.d("FragmentCreate","rhs userid "+rhs.getUserid()+" rhs remotelyentered "+rhs.isRemotelyEntered());
                        return -1;
                    }else if(lhs.isRemotelyEntered() && rhs.isRemotelyEntered()){
                        //return the lowest user id
                        //userid is of format Uxx ... so get the xx part begining from index 1 of the string and get the number
                        int lhsuserid = Integer.parseInt(lhs.getUserid().substring(1));
                        int rhsuserid = Integer.parseInt(rhs.getUserid().substring(1));

                        //Log.d("FragmentCreate"," The userids are lhsuserid "+lhsuserid+" rhsuserid"+rhsuserid);

                        //Do not get tempted to use String compareto function as this will give wrong results
                        // U11 will get priority over U4 in string compareto due to 1 being lexicographically smaller
                        //Thus never use lexicographical sorting ever.

                        //The user ids can never be equal as two remotely entered users will never have two entries (can't... it's impossible due to firebase)

                        if(lhsuserid<rhsuserid){
                            return  -1;
                        }else if(lhsuserid==rhsuserid){
                            //can never happen in real life... two remotely entered users can never have same id ever... just made for safeguard
                            return 0;
                        }else{
                            return 1;
                        }

                    }else if(!lhs.isRemotelyEntered() && !rhs.isRemotelyEntered()){
                        //both entered at POS and have same time
                        //can never happen in real life...
                        //made this just for testing scenarios in case i screw up and give wrong inputs
                        return 0;
                    }else{
                        //Log.d("FragmentCreate","lhs userid "+lhs.getUserid()+" lhs remotelyentered "+lhs.isRemotelyEntered());
                        //Log.d("FragmentCreate","rhs userid "+rhs.getUserid()+" rhs remotelyentered "+rhs.isRemotelyEntered());
                        return 1;
                    }
                }else{
                    return 1;
                }
            }
        };

        ArrayList<WaitlistedPerson> listOfPeople = new ArrayList<>();

        ValueEventListener eventListener = new ValueEventListener(){

            @Override
            public void onCancelled(DatabaseError error) {
                pw.println("<script>hideTimeTillTurn();</script>");
                pw.println("<script>changePosition('Sorry, some error occured');</script>");
                System.out.println("Sorry. some error occured");
            }

            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                int positionCounter=0;

                if(dataSnapshot.getChildrenCount()==1 || dataSnapshot.getChildrenCount() == 0 ){
                    //Log.d("FragmentCreate","This indicates that the restaurant probably closed down and removed all customers from the list");
                    pw.println("<script>hideTimeTillTurn();</script>");
                    pw.println("<script>changePosition('You are no longer in the waitlist');</script>");
                    System.out.println("You are no longer in the waitlist");
                }else{

                    if(dataSnapshot.hasChild(userId)){

                        double averageWaitTime=0.0d;

                        long timeEnteredInMillis=0;

                        listOfPeople.clear();

                        Iterable<DataSnapshot> peopleInList = dataSnapshot.getChildren();

                        for(DataSnapshot currentPerson : peopleInList){

                            if(currentPerson.getKey().equals("dummy")){
                                continue;
                            }

                            if(currentPerson.getKey().equals(userId)){
                                //This is our node.... break the loop and enjoy using the counter
                                averageWaitTime = currentPerson.child("averagewaittimeperparty").getValue(Double.class);
                                timeEnteredInMillis = currentPerson.child("timeentered").getValue(Long.class);
                                listOfPeople.add(new WaitlistedPerson(currentPerson));
                            }else{
                                listOfPeople.add(new WaitlistedPerson(currentPerson));
                            }

                        }

                        //sort the list using our custom comparator and the get the index

                        Collections.sort(listOfPeople,sortComparator);

                        //find the position of the user now

                        for(WaitlistedPerson person : listOfPeople){
                            ++positionCounter;
                            if(person.getUserid().equals(userId)){
                               break;
                            }
                        }

                        double timetillturn = Math.round(averageWaitTime * ((double)positionCounter));

                        long timeShouldComeAt = timeEnteredInMillis + (long)(timetillturn*60000);

                        Date timeWhenTurnArrives = new Date(timeShouldComeAt);

                        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

                        pw.println("<script>showTimeTillTurn();</script>");
                        pw.println("<script>changePosition('"+positionCounter+"');</script>");
                        pw.println("<script>changeTimeTillTurn('"+sdf.format(timeWhenTurnArrives)+"');</script>");
                        System.out.println(positionCounter+" "+sdf.format(timeWhenTurnArrives));

                    }else{
                        pw.println("<script>hideTimeTillTurn();</script>");
                        pw.println("<script>changePosition('You are no longer in the waitlist');</script>");
                        System.out.println("You are no longer in the waitlist");

                    }

                }

            }

        };

        waitlistRef.addValueEventListener(eventListener);

    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        try {
            pw.close();
        } catch (Exception e) {
            //do nothing here
        }
    }


}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request, response);
}

}

2 个答案:

答案 0 :(得分:0)

使用servlet,您的客户端不会看到任何页面更新,直到他们向您的应用程序服务器发送新请求。你可以做的是让你的ValueEventListener更新内存中对象的状态。然后,无论何时构造HTML输出,您的servlet都可以读取该对象的最新状态。

答案 1 :(得分:0)

所以我设法使用JSP而不是Servelet来解决这个问题。

在任何一种情况下,解决方案都是将所有逻辑转移到JavaScript函数。然后在体载上调用所述函数。

onload=callthefunction()

firebase侦听器已从java转换为JavaScript版本:

on()
off()

这种方式需要调用ajax或其他东西,需要更改的元素可以直接从JavaScript中更改