1
votes

What I'm trying to achieve is to only show the documents that match uid with user login. I've seen these examples on a lot of website but none of them seems to work for me. MyApp <- you can try on here, simple alarm webApp. It show all document from any user. this is my firestore collection: MyfireStore and here's my code *sorry for bad code, I still learning react:

function Alarm() {
  const dummy = useRef();
  const { uid, displayName } = auth.currentUser;
  const alarmRef = firestore.collection("alarm");
  const query = alarmRef.orderBy("detail").limit(10);
  const [alarm] = useCollectionData(query, { idField: "id" });
  const [alarmValue, setAlarmValue] = useState("");

  const sendAlarm = async (e) => {
    e.preventDefault();

    await alarmRef.add({
      detail: alarmValue,
      displayName,
      uid,
    });
    dummy.current.scrollIntoView({ behavior: "smooth" });
  };

  const stopAlarm = (e) => {
    e.preventDefault();
    document.querySelector(".Sound").pause();
    document.querySelector(".Sound").currentTime = 0;
  };

  const setAlarm = () => {
    var h = document.querySelector(".hours").value;
    var m = document.querySelector(".minutes").value;
    var ap = document.querySelector(".ampm").value;
    var hmap = `${h}:${m}:00 ${ap}`;
    setAlarmValue(hmap);
  };

  return (
    <>
      <form className="sectionInput">
        <div className="alrView">
          {alarm &&
            alarm.map((alr) => (
              <div>
                <AlarmView key={alr.id} alarm={alr} />
              </div>
            ))}
          <span ref={dummy}></span>
        </div>

        <div>
          <select className="hours" onChange={setAlarm}>
            <option>00</option>
            <option>1</option>
            <option>2</option>
            <option>3</option>
            <option>4</option>
            <option>5</option>
            <option>6</option>
            <option>7</option>
            <option>8</option>
            <option>9</option>
            <option>10</option>
            <option>11</option>
            <option>12</option>
          </select>
          <select className="minutes" onChange={setAlarm}>
            <option>00</option>
            <option>01</option>
            <option>02</option>
            <option>03</option>
            <option>04</option>
            <option>05</option>
            <option>06</option>
            <option>07</option>
            <option>08</option>
            <option>09</option>
            <option>10</option>
            <option>11</option>
            <option>12</option>
            <option>13</option>
            <option>14</option>
            <option>15</option>
            <option>16</option>
            <option>17</option>
            <option>18</option>
            <option>19</option>
            <option>20</option>
            <option>21</option>
            <option>22</option>
            <option>23</option>
            <option>24</option>
            <option>25</option>
            <option>26</option>
            <option>27</option>
            <option>28</option>
            <option>29</option>
            <option>30</option>
            <option>31</option>
            <option>32</option>
            <option>33</option>
            <option>34</option>
            <option>35</option>
            <option>36</option>
            <option>37</option>
            <option>38</option>
            <option>39</option>
            <option>40</option>
            <option>41</option>
            <option>42</option>
            <option>43</option>
            <option>44</option>
            <option>45</option>
            <option>46</option>
            <option>47</option>
            <option>48</option>
            <option>49</option>
            <option>50</option>
            <option>51</option>
            <option>52</option>
            <option>53</option>
            <option>54</option>
            <option>55</option>
            <option>56</option>
            <option>57</option>
            <option>58</option>
            <option>59</option>
          </select>
          <select className="ampm" onChange={setAlarm}>
            <option>AM</option>
            <option>PM</option>
          </select>
          <button className="submitTime" type="submit" onClick={sendAlarm}>
            Set Alarm
          </button>
          <button className="stop" onClick={stopAlarm}>
            Stop
          </button>
        </div>
      </form>
    </>
  );
}

function AlarmView(props) {
  const { detail } = props.alarm;
  const [timeNow, setTimeNow] = useState();

  const delAlarm = async (e) => {
    e.preventDefault();

    firestore.collection("alarm").doc(props.alarm.id).delete();
  };

  const UpdateTime = () => {
    let time = new Date().toLocaleTimeString();
    setTimeNow(time);
  };

  setInterval(UpdateTime, 1000);

  useEffect(() => {
    if (detail === timeNow) {
      document.querySelector(".Sound").play();
    }
  }, [UpdateTime]);

  return (
    <>
      <div className="timeAlarmBox">
        <h1>{detail}</h1>
        <h1 onClick={delAlarm} className="delAlarm">
          ❌
        </h1>
      </div>
      <div className="playback">
        <audio className="Sound">
          <source src={Sound} type="audio/mp3" />
        </audio>
      </div>
    </>
  );
}

you guys can try my app https://clockreivc.web.app/

2
Please be careful when leaving your Firebase out in the open as people with malicious intent could drive up your costs if you have not taken any measures such as rate-limiting etc. Costs can rise quickly. - boris
thank you for your advice sir, but I make all of this only for learning purpose thank you for reminding me - Ricky

2 Answers

1
votes

I got my answer when wake up in the morning xD

function AlarmView(props) {
  const { detail, uid } = props.alarm;
  const [timeNow, setTimeNow] = useState();
  let user = firebase.auth().currentUser;

  const delAlarm = async (e) => {
    e.preventDefault();

    firestore.collection("alarm").doc(props.alarm.id).delete();
  };

  const UpdateTime = () => {
    let time = new Date().toLocaleTimeString();
    setTimeNow(time);
  };

  setInterval(UpdateTime, 1000);

  useEffect(() => {
    if (detail === timeNow && user.uid === uid) {
      document.querySelector(".Sound").play();
    }
  }, [UpdateTime]);
  if (user.uid === uid) {
    return (
      <>
        <div className="timeAlarmBox">
          <h1>{detail}</h1>
          <h1 onClick={delAlarm} className="delAlarm">
            ❌
          </h1>
        </div>
        <div className="playback">
          <audio className="Sound">
            <source src={Sound} type="audio/mp3" />
          </audio>
        </div>
      </>
    );
  } else {
    return null;
  }
}

y'all can see I only add let user = firebase.auth().currentUser; and use if statement on return if (user.uid === uid)

0
votes

The CollectionReference you get from firestore.collection("alarm") has a where function which allows you to filter for where("uid", "==", <user-id>) or similar.

Another approach could be to have a per-user subcolletions alarm/<userid>. I think it is also possible to restrict user access to only the subcollection with the same user id.