# 投票專題 111上學期
[投票專題 Overview](https://hackmd.io/@zRWCfXc1TOaCsnINOAPeCw/HkkDB4G12)
[投票專題 111下學期](https://hackmd.io/nVW37qBfQiKJsjqVrHP1iQ?view)
---
# Important!
## Tools
[gitHub](https://github.com/not6914/voting)
[firebase](https://console.firebase.google.com/project/voting-cdea3/overview)
## 流程圖

## 細節
流程: 身分驗證(main.dart會連到那邊去)->進入選項頁面
選項頁面會有三個btn
### 1.建立投票
由按鈕以及textbox組成,一旦建立按鈕onPress,呼叫寫入firebase function,生成一個加入碼
生成加入碼之後,可以按回去選項頁面的按鈕
### 2.加入投票
先輸入加入碼,若這個加入碼是正確的,就從firebase讀取資料,併用這些資料來生成按鈕
當確定投票onPress,呼叫寫入firebase function,退回到選項頁面
### 3.察看結果
輸入加入碼查詢,會出現三種結果
#### a.加入碼不存在->跳提示,回選項頁面
#### b.加入碼存在但投票尚未結束->跳提示,回選項頁面
#### c.加入碼存在且投票結束->使用chart.dart(package)生成圖形
-------
# 1017Update - 問題出現!
## 之前有找過的簡單voting template(前幾次有demo的那個)
trace code之後,發現其實是他在切連到的其他檔案路徑有問題,才會出現登入成功之後load不出mock data
解法: 或許可以調整路徑,修正一下就可以了(猜想,並未嘗試)
## 上次說的template無法使用
1. packge版本衝突
原因: 幾個月前的更新,導致一直跳migrant to android 2
不太負責任的解法: yaml後面的參數都直接放any, 交給電腦去處理(但還是有問題)
問題點在cloud function跟launcher name需要的crypto package, firebase package版本不一樣(是因為launcher name一直停在0.0.1沒有更新)
2. build.gradle那邊抓不到google裡面的com.android.tools.build:gradle:3.6.3
因為它會連到jcenter(),解法就跟3.相同
3. 找不到maven的相關檔案
在build.gradle的repositories裡面改掉google()跟jcenter(),並替換成maven{url "..."}就可以解掉
[this template](https://github.com/baimamboukar/voting_system_app)
## 所以最後只能暫時用這份template code的想法來重寫一個
-----------------------------
# 1025 Update - Simple Voting App demo
## 實作進度
### 完成部分
- 1. 可以使用電子信箱匿名登入
- 2. 可以創立投票
- 3. 可以投票
### reference
[Ghauoor/polls_app_flutter](https://github.com/Ghauoor/polls_app_flutter)
## Template bugs
- OutlinedButton直接改flutter package?
- project中使用的polls package(v1.0.1 pub.dev第三方)用了舊的api(OutlineButton),所以其實還好

## APP bugs
- 有些人可以跑、有些人沒辦法
- sign up後沒反應
- 退出app後再按入有可能直接進入投票頁面
- 虛擬機不能跑但是用手機可以跑
- 投票結果無法在firebase反映出來,只能暫時看到自己投了什麼
- 每次重新登入都會變成無人投票的狀態(被清空)
- 投票時,100%的選項顏色卻只顯示一半
## 正常狀況
- 只要有人建立投票,大家都看得到,firebase會立即更新
## 之後
- 修bug
- 可以在firebase那邊成功顯示投票結果
- pollweight要正常紀錄(也就是避免下圖的情況)

- 也就是要fix無法寫入firebase的問題
- fix有人能登入、有人無法的情況
- 增加功能
- UI improve
- 驗證改掉匿名信箱登入,變成google sign in
- 可以創立不公開的投票
- 多選
## 建議
### 對demo方式的改進
**希望可以讓聽眾聽得更懂**
需要想一下**怎麼介紹這個產品**
可以想成當作產品發表的練習
1. 在展示一項功能前,要先說預期會又什麼功能
2. 為什麼要這樣設計
3. 想要解決現實生活中的什麼問題
4. 要讓不是這個領域的人聽得懂。
### 後續工作priority
優先修bug
版本問題處理->算bug
有時間再加新功能
## 可能AS沒有連到網路?
測試過了,不是這個問題
-----------------------------
# 1101 Update - Bug Fixing
## fixs
### database writing fix


從第一張圖片變成第二張圖片
問題解決!
方法:
1. collection的路徑打錯要記得修正
2. 請用set,不要用update(軟體實驗學到的經典用法,但上次demo前忘記)
3. set用完記得要做setoption merge(不然每次投票都會生一個新的decision,最後要用的時候會不知道要查哪個)
### 投票時,100%的選項顏色卻只顯示一半
我跑測試的時候就沒有這個問題了;照理來說這個不會有問題(這部分不是自己寫的,是直接用現成的API),也沒在開發者的github看到類似的留言
### Sign up之後沒反應

上圖的訊息只是一個warning,不會造成影響

1. 有可能是沒有接到網路
2. 有可能是按太快就馬上關掉(沒等firebase更新就直接做其他操作)
#### 仍無法解決(在吳振群那邊的問題)
## 新功能
### Google Signup 和 Login
目前能做到的情況是能顯示選擇要連結的Google account。

但是在點擊選擇了帳戶後,會跳出此error

以下這篇是查到比較完整的資料
[PlatformException(Stackoverflow)](https://stackoverflow.com/questions/56188338/platformexception-platformexceptionsign-in-failed-com-google-android-gms-comm#comment99004787_56188338)
裡面有提到許多可能的解決辦法。所以又去下面的cloud service做設定。
[Google Cloud API&Services](https://console.cloud.google.com/apis/credentials?project=voting-cdea3&supportedpurview=project)
目前暫時還在Debug嘗試中,但是我們上隔月在找各種template的時候,有其中一的google 登入是沒問題的,所以如果真找不到解方,可能會就會改成用他的方式來刻(但目前看起來在call api 上的寫法什麼問題,應該是因為有東西沒設定好。)
### 提醒
README要記得寫(環境設定相關)
-------------------------------
# 1108 Update
## 目前Google Login 碰到的問題
上周有提到,碰到的問題是在使用Google 登入時,會跳Exception,出現PlatformException:12500。
在Document上,就是Sign_in_fail。
這個問題其實在開發Android時很常見
[12500, an Android Developer’s nightmare…](https://dev.to/gattalraouf/12500-an-android-developer-s-nightmare-1i3b)
他的困難點就是從Error Message中看不出是出了什麼問題。
但是如果Google求解,會找到一個完整的流程來處理/檢查到底哪裡出了問題。
Step1:
> 檢查有沒有在firebase中開啟google sign in。
Step2:
> 有沒有填寫Supporting Email。
Step3:
> 有沒有在GCP的OAuth consent Screen Setting中設置firebase中顯示的Authoritize Domain。
Step4:
> 有沒有填寫SHA-1的fingerprint。
只要想要使用google登入,都要生成,也就是說,我們4個人都要將自己的SHA-1貼上去,雖然感覺有些不合理,像平時我們用其他app都不需要貼自己的key,但那是因為是用的會是google playstore去處理、生成的
Step5:
> 有沒有在GCP的OAuth consent Screen Setting中上傳要顯示的App Logo。
我們現在卡住的問題就是在檢查了上述5步驟後,仍有問題。
之前有說,會參考別人能跑的repo來跑。但是檢查後發現,其實再呼叫google sign in 的function時,其實寫法差不多,再補足了缺失package後,問題仍沒有解決。
原本想說先將firebase中google login disable,再重新啟動,結果出現不明錯誤無法啟動google login。
目前其他的功能(Email/Password,投票,增加decison)都正常,未受到影響,Google登入是完全不行(選擇gmail帳號也無法顯示)。
預計再另外開一個firebase Project,進行測試,如果仍不行的話,會暫時擱置,理由是這個功能並非High Risk,就不是投票APP,他是High Value,有做的話加分沒做的話影響不會太大。因此在短時間內無法處理的話我們的優先處理其他Bug和增加其他功能,等功能較完善後再來解決。
## README撰寫
## 關於多選設計
trace過polls.dart(別人寫好的API)。
polls.dart並不是官方的API文件,而是有人因為不想重複撰寫相似的code,便寫了一個package造福社會。
這個package的設計本來就是<font color="red">為了**單選**使用</font>(int userVoteChoice),而非多選。
基本上code都是重複的,是因為他做了八個選項才會看起來超多(那八個選項幾乎都是重複的、相似的code)。
### 目前想到的解決方法是直接從package更改別人的code
方法:
<font color="red">置換型別</font>(原本用來記錄投票結果的型別是int,可能換成stack就可以work了) +
<font color="red">切換單選多選</font>(用一個布林值卡住單選多選切換)
### 目前進度: 還在trace polls.dart檔案(總共1690行)
### TODO-list
1. 將userVoteChoice更改為stack(可以用stack package或是直接用array來維護)
2. 將原本選項上限為八個更改為更高(這個部分其實也可以選擇不做)
3. 增加用於單選、多選切換的布林值(同時,UI上也要有按鈕或開關來接收input)
4. 要能夠更改選擇,不能直接把flag拉起來、寫死(現在無法更改投錯的選項)
### 下周預期: 更改polls.dart檔案,以期望達成效果
## 下周目標
1. 多選設計完成
2. google sign in(可能)
## 建議
1. google sign in可以先擱置
2. 目前的READ.md可以
3. 投票結束有送出鍵(連結到回復上一動的功能)
4. 多選最多可以選幾個?(但我們最後是比例投票,可能用不到)
------------------------------------------
# 1114 Update
## 簡單統整目前還缺甚麼
### 需要在polls.dart中作的修改
1. userChoice改成陣列,並記得userChoice的size
2. voteData改成陣列(not sure)
2.應該不用,因為`voteData`在`widgets.dart`裡`class _PollsWidgetState`中的`Widget build(BuildContext context)`裡面
有這一行`voteData: widget.usersWhoVoted`去初始化
再來去找會更新到usersWhoVoted的部分只有在同一個地方(在`voteData: widget.usersWhoVoted`下面一點的`onVote: (choice) async...`)
應該只要在setState中改更新usersWhoVoted的code就好,不需改voteData的type
### polls.dart中可以多加的變數
1. canEdit變數,用來表示目前這個投票是處於可編輯的狀態
2. voteEndtime,用來記錄投票停止時間,一旦投票時間<現在時間,則在dachboard顯示結果(因為目前是隨時都可以看到投票情形的,需要將他卡住,直到voteEndtime小於現在時間才會顯示)
3. addCode,加入碼,一喘固定的數字,用來將私人的投票加入到search中
4. isMul變數,用來記錄現在這個投票是單選還是多選
5. isPublic變數,用來標記這個投票是不是一個公開的投票
### dashboard中可以添加的按鈕
1. clear button,用來將之前的有選的選項清空
2. submit button,用來將已經確定的投票內容送出到firebase
### 頁面
多加了一個搜尋頁面,用來抓私人投票到search
## 本周進度
### 多選
目前有在創立投票的時候放上是否為單選的按鈕
可以選擇多選,但有bug(多選的單一選項按下多次後,會重複計算)
現在多選不會顯示你投了沒(實際上有投,只是UI沒顯示)
### 私人投票
## 下周進度
1. 將多選的bug解掉(~~多選的單一選項按下多次後,會重複計算~~),還沒反映在UI上
3. 能夠search到private vote並加到search頁面(public vote無須搜尋)
4. add clear button
5. add submit button
6. voteEndtime,投票結束時間一到,要無法繼續投票並顯示結果
7. 創建私人後,需要顯示加入碼
8. mark出單選、多選的差別
## 建議
1. 重提submit button
2. 加入投票拿到decisionID,app-link(email上點到URL,可以直接連到這個app;點連結導入APP,然後將decisionID自動輸入到search text box)
3. voteEndtime改成管理員手動結束投票
-------------------------------
# 1122 Update
## 本周進度
### delete & submit button adding

目前按下delete按鈕會讓所有選票都變成0%,但會是無法投票的狀態。
第一個解決方法是在判斷`viewType == PollsType.readOnly`時,加入一個isDelete的flag,變成voterWidget,這個flag會從按下delete按鈕就變成1,但實作過程一直無法讓這個flag改變。
```cpp
if (viewType == PollsType.readOnly) {
//user can view his votes with this widget
if(isDelete == 1){
isDelete = 0;
return voterWidget(context);
}
return voteCasted(context);
}
```
第二個解決方法是按下delete按鈕之後就當作是重建一個投票,也就是呼叫`saveDecsion(Map pollsWeight, String title, bool isSingle)`,但這個方法有些參數吃不到,而且一但當作新的投票,可能這個投票的位置會移至分業最底層,會怪怪的。
暫時解決?
現在目前解到一半(11/25/20:00 hot-fix),已經能夠將整個userWhoVoted的部分清空,但這不是目前想要的效果;目前想要做到將userWhoVote中**特定user**的選擇清空。
### 選項UI顯示沒辦法跟LINE相似

LINE的這種顯示方式比較偏向checkbox,而非button
卡在的點是鼠標放置到文字上方點擊,仍需要將圓圈(checkbox)填滿
而checkbox需要點擊框,才能勾選
### search只能抓到private vote
將flag推到firebase上記錄,並且在畫到dashboard的時候,用這個flag阻止畫出private vote
但目前還沒有做到產生link的部分
### 多選bug fixed
1. potential bug
這是個很神奇的bug
跑測試時猜這個bug的意思是說最多只有[0][1], 沒有[1][1]這個東西
stack overflow上有人提出的問題和我們的問題並不相同(別人的解法是是initialize的問題,因為list開太多的問題)
所以一開始猜大概是list轉換的時候有少做事情 或是tolist()壞掉
那時的情況是多選也會變成單選,選了一個之後,因為第二個選項load不出來,不管你選哪個選項都會是第一個選項,所以只有第一個可以push上firestore

**最終解法**: 隔天晚上測試,突然就沒問題了(兩天間隔有將firebase內的資料刪除重整,也有可能是firebase上的資料造成這個問題的)
2. 如何解決"多選的單一選項按下多次後,會重複計算"的bug
一開始想用set解決,但debug console一直跳跟set有關的error,所以只好退而求其次用list
實作想法是檢查user目前選擇的選項有沒有出現在"他之前已經選擇過的list中",
如果有就不更新firebase
## 下周進度
1. 多選能顯示UI
2. delete bug fix
## 建議
1. delete -> reset
2. 選項先選起來->submit之後再把結果送出去(可能不需要使用delete直接跟firebase互動,而由submit跟firebase互動);也就是說,需要local的temp register(不需要選擇中時就頻繁寫入)
3. UI可以用顏色表示就好
# 1130 Update
## 本周進度
### 修好delete bug:
原本按delete只會清空userWhoVoted中自己的投票記錄,pollWeights依舊不變
現在按下delete後會更新pollWeights了
### 按下選項的UI變化:

polls.dart 新增8個bool flag btnPressed控制背景顏色,預設為false(意即尚未按下選項)
按下選項後背景會變色,再按一次顏色會消失
### 修好再次新增投票時,正確上傳投票選項
在還沒有處理前,同一帳號新增投票1(選項 A, B)後,將其清除再次新增投票2(選項 C, D),上傳的會是選項A, B, C, D,現在會在上傳到firebase後,將手機上的form做reset。
### 增加在add decision board 上顯示前次 新增的投票的id
### Timer
使用者可以輸入要倒數幾秒結束此投票,實作方法是先找到firebase的倒數秒數,使用`Timer.periodic`來處理每秒減一的狀態,並且讓此秒數顯示在投票欄的UI上。
bug : 沒辦法讓秒數一值下降,會停在使用者最先輸入的秒數。
solution : 可能可以每秒都更新firebase的值、先記錄想要的結束時間timestamp再用一些時間的函數來記錄現在的時間是否超過截止時間
```cpp=
var sec = widget.seconds;
Timer? timer;
timer = Timer.periodic(const Duration(seconds: 1), (_) {
sec--;
});
```
## 下周進度
1. 完成voteEndTime + 顯示投票結果
2. 將APP能夠放到ios系統
## 建議
1. 比較建議使用timestamp
2. app timestamp可能會因為時區出現問題(?) -> 這種問題還不需要解掉
3. Data Integrity -> 這種問題還不需要解掉
4. 另一種,前後端都要寫;前端(卡住使用者)、後端(送到時還要檢查一次)
---------------
# 1207 Final Demo
---------------
# 1213 Update
# Outline
1. 看private bug能不能修好(問題點條列在最後)
2. 未來願景以及需要完成願景延伸的功能
## 本周發現以及回覆上次沒回答完整的問題
### 並沒有一個完整的前後端架構
整份project確實沒有寫到firebase的部分,最多只有從firebase裡面撈資料。
所以說目前的後端部分是沒東西的,整份專案偏向前端。
### setState && notifylistener兩種更新方式
上次有提到想了解一下我們在dashboard那邊的更新模式(也有提到說可以嘗試看看多用一個reload按鈕),以下簡短介紹我們在這份project中使用到的兩種更新方式:
* setState: 每次setState需要rebuild widgets,如果是隔很多層的傳遞,需要被rebuild的widgets會越多,相對效能會比較差,僅適合小規模的更新。
* notifylistener: 繼承一個Model Class,然後自定義你的Model,像是CountModel或SearchModel,並在狀態改變時執行notifyListeners()
#### 比較:
| X | setstate | notifylistener |
| -------- | -------- | -------- |
| layer level | 比較高層 | 比較底層 |
| 用React來舉例 | react的setstate | react的context(在ref中看到的) |
#### 結論:
哪個比較有效率? 其實都差不多,都是狀態更新之後才會資料傳遞。
reference: [30天學flutter](https://ithelp.ithome.com.tw/articles/10217200)
## 未來願景以及需要那些功能
期望往更重要的使用時機走。現在的版本**只適用在課堂**上,對那些無關緊要的問題做出選擇,而投票者也不太在乎結果;
### 期望可以提升到"公司或學校高層的投票決議"
先定義一下"公司或學校高層的投票決議"。
1. 人數不會超過20個人
2. 對於私人投票有需求
3. 大家為了趕時間所以需要一個快速的投票方式
**所以需要**
- 確保投票流程是順暢的(頁面標示直覺、操作符合期待)
- 確保投票資料安全
- 需要回顧投票結果且在意投票結果
一句話總結就是: <font color = red>**方便、簡結、快速、安全**</font>
而目前我想到的解決方案(or how to improve this)
### 1. 重新設計頁面
往更重要使用時機走,勢必要多做回顧歷史紀錄相關的功能。也就是說,頁面需要重新設計(現在的頁面會變得很雜);所要提出的,是個人資料相關全部分到同一個頁面,裡面包含個人資訊(email)、可以摺疊的歷史紀錄(=投票結果、那些自己投過票且已經結束的投票)、設定過的私人投票邀請碼。
### 2. 改善私人投票的邀請碼機制
一個一個輸入邀請碼會是一件不太符合某些需要在短短時間做出決策的情況,因此這點也需要改善。可能可以換成QRcode,只不過換成QRcode之後的運作模式還需要多加了解。
### 3. 安全性
這個目前還沒有想法。
## bugs
私人單選(&多選)delete不能按(甚至出現負票)
以及投票時間終止後,仍可投票
私人多選end後,不會顯示結果
私人多選直接顯示結果,但投票者沒投票
---------------
# 1219 Update(小抄)
1. sign in & out & 底下的4功能一句話
2. 投票流程
creator怎麼新增投票(最多幾選項)、講end button
voter去dashboard看title,mode,options,講delete,submit
3. private
[投影片在這裡](https://hackmd.io/@WqkHA-SGS0O01qt_nA69mA/HysDoL6ds)
---------------
# 1220 Update
## Outline
1. bug fixing
2. 關於私人投票的QRCode機制
## bug如何解決
簡單敘述一下上次私人投票的bug
1. 投票時間終止後,仍可投票
2. 私人多選end後,不會顯示結果
3. 私人多選直接顯示結果,但投票者無沒投票
4. reset按鈕無法正確清空(刪除)投票底下的list
### check-list
- [x] 投票時間終止後,無法繼續投票
- [x] 私人多選end後,可以顯示結果
- [x] 私人多選不會直接顯示結果,且投票者無法投票
- [x] reset按鈕正確清空(刪除)投票底下的list
- [x] reset時能夠正確的在重複submit時,更新票數和list
## 周一發現的其他問題
1. 在電腦不使用網路進行build&install時,是無法將APP下載到手機的(原本以為不使用網路、單靠電腦上的project也可以成功build)
2. 在資料庫刪除帳號後,使用者依舊可以使用這個APP
## QRCode安全機制
### 跟帳號密碼連動
上次有提到的,為了不是所有人都可以輕易的使用這個QRcode,所以需要身分認證(帳號密碼連動)
<b>網路上的做法</b>
reference:
<b>我們適合的做法</b>
### 其它想法
## Firebase的後端?

## 建議
1. QRCode相關
2. 網路造成的問題(先check是不是網路造成的、再嘗試解掉)
# 1227 Update
## 大方向
1. 區分程式碼中,一般功能跟與資料庫互動的功能(嘗試透過這樣區隔開的方式來改善管理)
2. 調整頁面配置
3. QRCode實作(from basic ver. to advanced ver.)
4. 觀看學長給的auth_token影片(每個人都要了解一下)
## 本周進度
### Outline
1. 測試哪裡有bug、調整code
2. 對網路的問題測試,觀察沒有接到網路的情況下會是甚麼行為
3. QRcode Research
4. 觀看學長給的auth_token影片
### 測試
1. private vote在search那邊(下圖為在search頁面創建vote UI的code),可以確定是要放validVoteList沒錯、而非docs[index]...(上次demo出現問題有部分是這個造成的)

2. widget.dart選取的部份(下圖)其實不需要使用isSingle卡住(當初使用isSingle的目的是想式看看能不能因為這樣解決掉單選只能投一個選項的問題,而現在解決這個問題的部分在polls.dart)

3. APP裡面有跑出東西,但firebase裡面是空的


sol: 猜測是那一台虛擬機自己的問題,因為換一台就沒事了。
### 網路造成的問題?
1. 已經確認過沒有使用到跟offline caching相關的function及功能
2. 接下來跑一些實驗
#### 實驗部分
Case 0 - enter
- 無法authemticate
- 卻可以在已經登入的裝置,退出後進到home page
- 切換頁面沒有問題
Case 1 - create
- 如果不接網路的情況下,按下創建投票可以成功?
- result: 可以成功,在創建這端,會直接顯示出創建的投票。
- 如果在上述的情況下,按下創建投票後再接上網路,情況會是甚麼?
- result: 如果一直停留在dashboard的話,並不會馬上更新(狀態沒有改變),因此需要切換頁面、再切回來,或是點一下螢幕。
Case 2 - vote
- 如果不接網路的情況下,按下投票選項可以投嗎?
- result: 選項會亮起來。
- 如果在上述的情況下,按下投票選項再接上網路,情況如何?
- result: 同上述的情況。
Case 3 - submit
- 如果不接網路的情況下,按下送出投票可以正確送出嗎?
- result: 無法送出到資料庫。
- 如果在上述的情況下,按下送出投票再接上網路,情況如何?
- result: 點了一下螢幕之後,就成功寫到資料庫了。
Case 4 - reset
- 如果不接網路的情況下,按下清除投票可以正確清除嗎?
- result: 選項這邊是已經讓他變回白色了,但實際情況是還沒送到資料庫。
- 如果在上述的情況下,按下清除投票再接上網路,情況如何?
- result: 接上網路後,點一下螢幕就馬上清除了。
- Fact: 當在沒有網路的情況下,按了選項、按下送出、再按下清除,不會更新到資料庫;一旦接上網路,資料庫那邊的行為是先寫入選項、再清除(也就是執行順序並沒有因為斷網而亂掉)。
Case 5 - end
- 如果不接網路的情況下,按下結束投票可以正確結束嗎?
- result: 可以正常結束。會顯示斷掉網路前收到的票數。
- 如果在上述的情況下,按下結束投票再接上網路,情況如何?
- result: 如果斷網期間,票數有更新的話,就會在重新接上網路之後更新票數。
Case 6 - search
- 如果不接網路的情況下,輸入搜尋投票可以正確加入嗎?
- result: 關掉網路的情況下,可以找的到投票。
- 如果在上述的情況下,輸入搜尋投票再接上網路,情況如何?
- result:
- 找到問題了! 私人投票的投票者在關掉網路的情況下,一旦創建者按下結束,所有人都不會顯示結果,而是可以繼續投票。不管是創建者按下結束、或是資料庫突然更改結束相關的變數,都會造成這個結果。這個結果無法經由再次打開投票、再關起來就輕鬆解決,只能通過將APP rebuild解決或是刪除這個投票。
#### 小結
1. 前面的實驗裡,我們可以大致上猜測到,其實手機程式是有cache的存在;因為cache的緣故,所以重新接到網路之後,每次指令就像是從ready queue一個一個pop出來的感覺,一次次的更新資料庫。
2. 無法還原demo時候出現的bug。
3. 關於找到的問題點,猜測isEnd並不會在重新連接網路之後,覆蓋掉舊isEnd。
reference:
1. [Cache Management](https://medium.flutterdevs.com/cache-management-in-flutter-35a374c14303)
2.

### QRcode
#### 核心概念?
產生QRCode的時候,widget會需要一個key property來做渲染(為了要從byte變成圖片);而這個key是self define(而我們這邊這個key可以放未經處理的邀請碼)。
#### 想法(Naive):
可以check是不是已經在user中有帳號。
#### 難點:
1. creator無法知道誰可以投誰不能投(匿名性)
2. 就算限制投票時間也無法確定連結是否外流
#### 兩個產生QRCode的方法:
其中一種方法:
使用firebase的dynamic links,可以實現產生QRCode。
另一種:
1. BarcodeScanner.scan()這個API可以用來掃描QRCode(前提是要有相機的權限)。
2. 而在產生QRCode的時候,會需要一個key值來做渲染(為了要從byte變成圖片)
reference:
1. [Scan QR Code To Open Specific Content In An App](https://techpearl.com/blog/scan-qr-code-to-open-specific-content-in-the-app/)
2. [Building Flutter QR Code Generator, Scanner, and Sharing App](https://medium.com/flutter-community/building-flutter-qr-code-generator-scanner-and-sharing-app-703e73b228d3)
3. [[Day13] Flutter with GetX qr_flutter & qr_code_scanner](https://ithelp.ithome.com.tw/m/articles/10273055)
## 下周進度
目前確定checkDecision這個頁面不會改動了(一定會留著的意思),而QRcode會做在這個頁面<b>i.e. 使用者可以在這裡選擇要複製邀請碼、或是產生QRCode</b>;
也確定頁面的部分要做調整(同之前的報告內容);
而調整頁面這部分不會影響到QRcode的頁面,因此這兩部分可以拆成兩組、同時進行。
產生QRcode(掃了還沒反應,認證相關的還不用做)
預計下周完成的部分有
1. 完成國科會計畫的申請
2. 頁面已經重新arrange了(有些頁面可以是空的)
3. debug
## 建議
## 一些想法
要投票的人,在創建投票之前,需要知道幾個人投;
接著依照人數生成隨機帳號,並需要像隨機抽牌那樣,隨機分帳號的投票者(分給別人帳號密碼的方式可以用RSA);
使用隨機帳號投票。
如果要做這種方法,一定需要自動填入的功能,不然連測試都會很痛苦。
# 0103 Update
## 本周進度
1. 先講一下上次實驗部分,程式運作原理大概長甚麼樣子
2. UI更新
3. 國科會表格填寫
### 原理
Case 0 - enter
- 上次的部分(Recall)
- 無法authemticate
- 卻可以在已經登入的裝置,退出後進到home page
- 切換頁面沒有問題
- 順一下流程
- main裡面會先確定snapshot後有沒有data(snapshot.hasdata)
- 之後決定要不要進入登入頁面或主頁面
- 實作細節
- 這邊用streambuilder來實作(import async.dart)
- streambuilder依靠的是事件流(這邊我們訂閱,即subscribe了authstate),因此只要authstate(定義在firebase_auth.dart)更改就會生出新的事件給streambuilder
- snapshot.hasdata會接到async.dart裡面的data(local變數)

- 而這裡就要去看到firebase_auth.dart的authStateChanges,而我也有在stackoverflow上面看到有人問authStateChanges的相關問題
- 但並沒有問到跟我們這邊相同的問題(停用網路會發生甚麼事...之類的)
- 可以確定的是
- 一旦build成功,並且在已經接上網路、成功登入APP之後,斷網後重新進入APP,接著就會進入dashboard
- 上面那件事情必然成立,是正常現象。
- 因為一旦登入過後,authstate有值,不會是null;所以snapshot.hasdata也不會是null
- 接著由於關掉APP、重新進入,會直接回到main,main裡面又會交由hasdata來判斷要navigate到哪邊,所以會快速的切到dashboard(這裡要強調,main.dart沒有一個自己的頁面,所以也看不出來)
- 最後,在斷網的時候也可以切換頁面(左右滑動),是因為負責控制所有頁面的程式沒有跟網路互動(這個控制所有頁面UI功能的地方是寫死的)
- Reference:
- [Flutter StreamBuilder使用介紹](https://www.jianshu.com/p/2455c1d75608)
- [Youtube StreamBuilder intro.](https://www.youtube.com/watch?v=MkKEWHfy99Y)
- [authstatechages problem](https://stackoverflow.com/questions/64520543/struggling-with-authstatechanges-in-flutter)
Case 1 - create
- 上次的部分(Recall)
- 如果不接網路的情況下,按下創建投票可以成功?
- result: 可以成功,在創建這端,會直接顯示出創建的投票。
- 如果在上述的情況下,按下創建投票後再接上網路,情況會是甚麼?
- result: 如果一直停留在dashboard的話,並不會馬上更新(狀態沒有改變),因此需要切換頁面、再切回來,或是點一下螢幕。
- 可以確定的部分
- 'Decision Uploaded'這個會顯示是沒錯的,這個部分跟網路沒有互動
- 而在上傳投票的部分,會使用的firebase的API(add function),而我在collection_reference.dart那邊有找到他的實作code
- 
- 也就間接地證明了,我們之前的推論是正確的,i.e. ToFirestore這個資料結構可以先暫存我們發出的指令,我們需要等到連上網路之後才能做query
- 而為何發送端可以直接在UI把投票畫出來呢? 是因為ToFirestore這個資料結構在query.dart也有用到(這是在dashboard那邊,stream訂閱的東西 -> firebase.collection.snapshot)
- 而創建投票的時候會state change,由於這個資料結構其實是共享的,API就不需要從firebase那邊抓新的值了,於是會從ToFirestore那邊直接拿來用,所以更新也沒問題
Case 2 - vote
- 上次的部分(Recall)
- 如果不接網路的情況下,按下投票選項可以投嗎?
- result: 選項會亮起來。
- 如果在上述的情況下,按下投票選項再接上網路,情況如何?
- result: 同上述的情況。
- 這邊都和網路沒有關係
- 按下投票時,只會改變local端的list
- 並不會和網路互動
Case 3 - submit
- 上次的部分(Recall)
- 如果不接網路的情況下,按下送出投票可以正確送出嗎?
- result: 無法送出到資料庫。
- 如果在上述的情況下,按下送出投票再接上網路,情況如何?
- result: 點了一下螢幕之後,就成功寫到資料庫了。
- 從firebase.set()那邊trace,可以連到document_reference.dart去看source code
- firebase.set()那邊也是使用ToFirestore, FromFirestore這個資料結構
- 而document_reference.dart他是cloud_firestore的一部分
- 所以這邊跟前面的一樣,如果在沒有網路的情況下,在本地端更新(UI的部分可以演出來,因為可以直接從那兩個資料結構取值),但需要等到網路連線之後,再送到資料庫
Case 4 - reset
- 上次的部分(Recall)
- 如果不接網路的情況下,按下清除投票可以正確清除嗎?
- result: 選項這邊是已經讓他變回白色了,但實際情況是還沒送到資料庫。
- 如果在上述的情況下,按下清除投票再接上網路,情況如何?
- result: 接上網路後,點一下螢幕就馬上清除了。
- Fact: 當在沒有網路的情況下,按了選項、按下送出、再按下清除,不會更新到資料庫;一旦接上網路,資料庫那邊的行為是先寫入選項、再清除(也就是執行順序並沒有因為斷網而亂掉)。
- 和Case 3 - submit相同
Case 5 - end
- 上次的部分(Recall)
- 如果不接網路的情況下,按下結束投票可以正確結束嗎?
- result: 可以正常結束。會顯示斷掉網路前收到的票數。
- 如果在上述的情況下,按下結束投票再接上網路,情況如何?
- result: 如果斷網期間,票數有更新的話,就會在重新接上網路之後更新票數。
- 和Case 3 - submit相同
- 而上次懷疑可能斷網後重新連接的投票者,會直接覆蓋掉原本的isEnd值 -> 這是有可能的,因為我們在做isEnd的更新沒有多加判斷式,而是直接call firebase API,將isEnd merge;也就是說,只要有人存錯IsEnd的值,那麼所有人的isEnd值都有可能因此改變
Case 6 - search
- 上次的部分(Recall)
- 如果不接網路的情況下,輸入搜尋投票可以正確加入嗎?
- result: 關掉網路的情況下,可以找的到投票。
- 如果在上述的情況下,輸入搜尋投票再接上網路,情況如何?
- result:
- 找到問題了! 私人投票的投票者在關掉網路的情況下,一旦創建者按下結束,所有人都不會顯示結果,而是可以繼續投票。不管是創建者按下結束、或是資料庫突然更改結束相關的變數,都會造成這個結果。這個結果無法經由再次打開投票、再關起來就輕鬆解決,只能通過將APP rebuild解決或是刪除這個投票。
### 找資料? 結論?
1. FlutterFire並沒有對使用到的特殊資料結構(ToFirestore)多加解釋
2. 而直接到import的dart檔案裡面,是看不到這個資料結構的定義的;google也搜尋不到有甚麼有用的東西
3. 其實firebase(FullterFire)也有相關的API來對cache操作(離線操作),但我們沒使用到{這部分stackoverflow資料相較起來偏少}
4. 可以換個角度想,是否可以將需要用到網路的操作跟不需要的分開,再根據網路連接狀況決定是否需要離線操作
reference: [官方網站對access data offline的舉例(document)](https://firebase.flutter.dev/docs/firestore/usage/#access-data-offline)
### 介面調整
-  home介面更改
-  新增向右拉的頁面,並且把個人資料相關放在這邊(因此可以看到user的相關資訊)
-  頭貼的部分也有自己的頁面
-  自己創立的投票邀請碼會出現在這裡
-  投票的歷史紀錄(你投過哪個投票、查看投票結果)
-  尋找私人投票的頁面改放到正中間
### 國科會的資料填寫進度
此計畫申請用意在取得經費補助,需要填寫的項目蠻多的,包括基本資料、研究計畫中英文摘要、研究計畫內容以及很多的經費申請項目,有以下經費可以申請

依照學長之前的區塊鏈主題範本,研究計畫分成七個項目來寫(可以自己訂標題以及標題數量)
(⼀) 摘要
(⼆) 研究動機與研究問題
(三) ⽂獻回顧與探討
(四) 研究⽅法及步驟
(五) 預期結果
(六) 參考⽂獻
(七) 需要指導教授指導內容
目前粗略寫了研究動機,但觀察學長寫的內容很多都是區塊鏈相關的專業知識,我們目前都還沒開始研究區塊鏈的領域,不知道能不能寫得出這份申請表,而且主要目的是要申請經費,但我們目前只需要firebase後端的付費內容,感覺應該要做更多之後才會發現我們需要那些補助,目前沒什麼概念,所以要在2/20之前趕快進入區塊鏈或者安全晶片的領域?需要跟學長談談。
## 建議
1. [正確的表格](https://www.nstc.gov.tw/folksonomy/list/2af9ad9a-1f47-450d-b5a1-2cb43de8290c?l=ch)
2. 回到投票本身,以投票為主軸。需要甚麼東西來保護投票的完整性?安全性?裝置?
3. 版圖?有沒有人做過類似的東西?現在其他人開發的問題在哪裡?
4. 剩下的都可以討論
5. 可以從線上投票的問題來看(從新聞、報告也可以) -> 公正性有疑慮 -> 安全 + 便利(手機)
6. 安全晶片、區塊鏈如果要用,需要多做論述,來說明他能不能保證安全
7. 先做一個初步成果,再慢慢修改
## 下一次meeting 2/1?
過年完才會再次meeting
# 0127 Update
## requirement的筆記
英文的part來自{2017 A review of contemporary e_voting / Requirements technology systems and usability}
中文的part可以到{2022_MOST_E-voting}這邊去看(pg.6)
1. 完整性、可靠性
2. 匿名性
3. 不可重複使用
4. 資格
5. 耐操性
6. 可驗證
7. 可使用性
8. 公平
9. 不可脅迫
tally: 紀錄
- Re-encryption Mix-net:
the mix-net (or a shuffle agent) needs not decrypt the ciphertext, but to use the authority public key and transform the ciphertext into another number where the decryption of this ciphertext remains unchange.
ballots are treated as ciphertext and be collected by different shuffle agents.
- Homomorphic Encryption
Homomorphic => allows one to aggregate ciphertexts without decrypting them
- Secret Sharing
is a cryptographic tool that allows a group of at least k members holding shares to decrypt a cipher while group less than k member would be unable to decrypt it.
- Blind Signature
When it is used in e-voting context, a voter will demand the authority to blindly sign on a concealed ballot. The voter then casts the unblinded ballot anonymously. In the tally phasing all anonymous vote will be published. If a voter cannot find his vote under a possibly exclusion of his vote, he can present an evident of the blinded ballot was signed by the authority.
簡單講,就是為了要證明投票者是對的人。
- Anonymous Submission
allow someone to contribute its input in a vector without letting other knowing where it is submitted to.
- Zero-knowledge Proof
A zero-knowledge proof protocol allows a prover to demonstrate a statement is indeed what it is claimed without revealing any addition knowledge about it.
- Deniable Signature / Designated Verifier Signature
allow a signer to send a signed message to a designated verifier who can be convinced that the message is composed by the signer and the signer can later deny the signature to other verifiers by composing another entirely different message but with the same signature.
DVS => This technique allows a voter to convince an authority a ballot is indeed sent by this voter while the voter can deny this ballot to any vote buyers to prevent any sort of coercion.(only allows a voter to lie about his vote, but it cannot help against a voter who wants to make his encryption undeniable.)

發想:
核心會是網路投票(online election)在手機上的應用
我們需要甚麼東西來讓這個題目成立(實現)?
關於投票"安全"的各個條件,需要甚麼技術來輔助?
為了要確保我們完成的裝置是安全的,於是我們需要藉由密碼學以及區塊鍊的方法,來完成我們提出的裝置。 //用裝置這個詞好像怪怪的
由於這個產品需要放到手機上使用,因此對於運行速度跟佔用空間也都要注意。
可信的執行環境
提供證明選票的真正來源
投票需要的component: voter, register(知道參與者是誰的list), pollster(投票介面 顯示票的敘述 使用者端), validator(用來驗證投出去的票 是不是參與者投的), tallier(用在結束投票候 證明選票的真正來源)
1. 完整性、可靠性
區塊鍊
2. 匿名性
區塊鍊
blind signaature(學習M-SEAS的技術)
3. 不可重複使用
4. 資格
5. 耐操性
6. 可驗證
區塊鍊
//從ivote那邊學verification protocol
7. 可使用性
8. 公平
9. 不可脅迫
//密碼學的方式? 這部分是必要
//區塊鍊? 不確定必不必要(學長說這depend on 我們的選擇)
//步驟的部分,使用甘特圖(補助期程 112年7月1日至113年2月底)
步驟:
先進行理論部分研究(上面提到的研究方法一一讀過或使用) -> 實作與調查同步進行 -> 實作完畢進行測試 -> 版本更新 -> 更新結束再一次測試 -> 最終版本