Skip to content

Commit 3ace22d

Browse files
committed
Refactor pagination to user offset, add testing and expand filtering
2 parents f8c723c + 30c6dbd commit 3ace22d

File tree

9 files changed

+354
-85
lines changed

9 files changed

+354
-85
lines changed

firebaseSample/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
This is the Firebase Golang code. It's meant for the backend people to use this code to jumpstart their own REST API development
2+
3+
## Getting Started
4+
5+
First, run the development server by running `main.exe`
6+
7+
Open [http://localhost:8080/question](http://localhost:8080/question) with your browser to see the result.
8+
9+
Remember to place the `cs3219-g24-firebase-adminsdk-9cm7h-b1675603ab.json` file in the same directory/folder as `main.exe`
10+
11+
DO NOT UPLOAD THE `cs3219-g24-firebase-adminsdk-9cm7h-b1675603ab.json` FILE ONTO GITHUB, OR ELSE THE FIREBASE CODE WILL STOP WORKING!!!
12+
Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package handlers
22

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
7+
"log"
68
"net/http"
79
"question-service/models"
810
"question-service/utils"
11+
12+
"cloud.google.com/go/firestore"
13+
"google.golang.org/api/iterator"
914
)
1015

1116
func (s *Service) CreateQuestion(w http.ResponseWriter, r *http.Request) {
@@ -18,23 +23,71 @@ func (s *Service) CreateQuestion(w http.ResponseWriter, r *http.Request) {
1823
return
1924
}
2025

21-
// Update database
22-
docRef, _, err := s.Client.Collection("questions").Add(ctx, map[string]interface{}{
23-
"title": question.Title,
24-
"description": question.Description,
25-
"complexity": question.Complexity,
26-
"categories": question.Categories,
26+
// Validation
27+
// TODO: Duplicate checking for question name
28+
29+
// Reference to the document where we store the last ID
30+
counterDocRef := s.Client.Collection("counters").Doc("questions")
31+
32+
// Firestore transaction to implement auto-increment
33+
err := s.Client.RunTransaction(ctx, func(ctx context.Context, tx *firestore.Transaction) error {
34+
doc, err := tx.Get(counterDocRef)
35+
if err != nil {
36+
return err
37+
}
38+
39+
// Get the current value of the counter
40+
currentCounter := doc.Data()["count"].(int64)
41+
newCounter := currentCounter + 1
42+
43+
// Update the counter in Firestore
44+
if err := tx.Set(counterDocRef, map[string]interface{}{
45+
"count": newCounter,
46+
}); err != nil {
47+
return err
48+
}
49+
50+
// Use the newCounter as the ID for the new document
51+
docRef, _, err := s.Client.Collection("questions").Add(ctx, map[string]interface{}{
52+
"id": newCounter,
53+
"title": question.Title,
54+
"description": question.Description,
55+
"complexity": question.Complexity,
56+
"categories": question.Categories,
57+
"createdAt": firestore.ServerTimestamp,
58+
})
59+
if err != nil {
60+
http.Error(w, "Error adding question", http.StatusInternalServerError)
61+
return err
62+
}
63+
64+
// Get data
65+
doc, err = docRef.Get(ctx)
66+
if err != nil {
67+
if err != iterator.Done {
68+
http.Error(w, "Question not found", http.StatusNotFound)
69+
return err
70+
}
71+
http.Error(w, "Failed to get question", http.StatusInternalServerError)
72+
return err
73+
}
74+
75+
// Map data
76+
if err := doc.DataTo(&question); err != nil {
77+
http.Error(w, "Failed to map question data", http.StatusInternalServerError)
78+
return err
79+
}
80+
question.DocRefID = doc.Ref.ID
81+
82+
return nil
2783
})
2884
if err != nil {
29-
http.Error(w, "Error adding question", http.StatusInternalServerError)
85+
log.Fatalf("Trasaction failed: %v", err)
3086
return
3187
}
3288

33-
// Map data
34-
question.Ref = docRef.ID
35-
3689
w.Header().Set("Content-Type", "application/json")
3790
json.NewEncoder(w).Encode(question)
3891

39-
fmt.Fprintf(w, "Question with ID %s created successfully", question.ID)
92+
fmt.Fprintf(w, "Question with ID %s created successfully", question.DocRefID)
4093
}

services/question-service/handlers/delete.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ func (s *Service) DeleteQuestion(w http.ResponseWriter, r *http.Request) {
1313
ctx := r.Context()
1414

1515
// Parse request
16-
id := chi.URLParam(r, "id")
16+
docRefID := chi.URLParam(r, "docRefID")
1717

18+
// Reference document
19+
docRef := s.Client.Collection("questions").Doc(docRefID)
20+
21+
// Validation
1822
// Check if exists
19-
_, err := s.Client.Collection("questions").Doc(id).Get(ctx)
23+
_, err := docRef.Get(ctx)
2024
if err != nil {
2125
if status.Code(err) == codes.NotFound {
2226
http.Error(w, "Question not found", http.StatusNotFound)
@@ -27,11 +31,11 @@ func (s *Service) DeleteQuestion(w http.ResponseWriter, r *http.Request) {
2731
}
2832

2933
// Update database
30-
_, err = s.Client.Collection("questions").Doc(id).Delete(ctx)
34+
_, err = docRef.Delete(ctx)
3135
if err != nil {
3236
http.Error(w, "Error deleting question", http.StatusInternalServerError)
3337
return
3438
}
3539

36-
fmt.Fprintf(w, "Question with ID %s deleted successfully", id)
40+
fmt.Fprintf(w, "Question with ID %s deleted successfully", docRefID)
3741
}

0 commit comments

Comments
 (0)